android Butter Knife 使用详解
Butter Knife
github连接:https://github.com/JakeWharton/butterknife
本文使用的butterknife版本7.0.1
butterknife:使用依赖注入的方式为你的Android views绑定字段方法。
1控件绑定
通过使用@bind和一个资源ID,butterknife会自动绑定到layout中声明资源。textview为例
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.TextView; import butterknife.Bind; import butterknife.ButterKnife; public class MainActivity extends AppCompatActivity { @Bind(R.id.title) TextView title; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); title.setText("this is a test"); } }
2 res资源绑定
通过使用@BindBool
, @BindColor
, @BindDimen
, @BindDrawable
, @BindInt
, @BindString
,绑定预定义的资源;
public class MainActivity extends AppCompatActivity { @BindString(R.string.app_name) String appName; @BindDrawable(R.mipmap.ic_launcher)Drawable drawable; @BindColor(R.color.colorAccent) int color; @BindDimen(R.dimen.activity_horizontal_margin) int margin;// int (for pixel size) or float (for exact value) field @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); } }
3 Fragment中的绑定
public class FancyFragment extends Fragment { @Bind(R.id.button1) Button button1; @Bind(R.id.button2) Button button2; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fancy_fragment, container, false); ButterKnife.bind(this, view);//这里调用的是bind(context,view)方法 // TODO Use fields... return view; } }
4 Adapter中的绑定
public class MyAdapter extends BaseAdapter { @Override public View getView(int position, View view, ViewGroup parent) { ViewHolder holder; if (view != null) { holder = (ViewHolder) view.getTag(); } else { view = inflater.inflate(R.layout.whatever, parent, false); holder = new ViewHolder(view); view.setTag(holder); } holder.name.setText("测试"); return view; } static class ViewHolder { @Bind(R.id.title) TextView name; @Bind(R.id.job_title) TextView jobTitle; public ViewHolder(View view) { ButterKnife.bind(this, view); } } }
其他绑定API:
-
使用Activity为根视图绑定任意对象时,如果你使用类似MVC的设计模式你可以在Activity 调用ButterKnife.bind(this, activity),来绑定Controller。
-
使用ButterKnife.bind(this)绑定一个view的子节点字段.如果你在子View的布局里或者自定义view的构造方法里 使用了inflate,你可以立刻调用此方法。或者,从XML inflate来的自定义view类型可以在onFinishInflate回调方法中使用它。
5View集合中的使用
可以将多个view组成一个List或数组。
@Bind({ R.id.first_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;
apply方法可以一次作用到所有的View。
ButterKnife.apply(nameViews, DISABLE); ButterKnife.apply(nameViews, ENABLED, false);
Action 和 Setter 接口可以指定简单的行为。
static final ButterKnife.Action<View> DISABLE = new ButterKnife.Action<View>() { @Override public void apply(View view, int index) { view.setEnabled(false); } }; static final ButterKnife.Setter<View, Boolean> ENABLED = new ButterKnife.Setter<View, Boolean>() { @Override public void set(View view, Boolean value, int index) { view.setEnabled(value); } };
Android的Property(配置信息)也可以被用在apply方法中
ButterKnife.apply(nameViews, View.ALPHA, 0.0f);
6.监听器绑定
Butter knife可以自动将侦听器配置为方法。
@OnClick(R.id.submit) public void submit(View view) { } @OnClick(R.id.submit) public void submit() { } //定义的指定类型将会被自动转换 @OnClick(R.id.submit) public void sayHi(Button button) { button.setText("Hello!"); }
指定多个id在一个单一的绑定事件中处理。
@OnClick({ R.id.door1, R.id.door2, R.id.door3 }) public void pickDoor(DoorView door) { if (door.hasPrizeBehind()) { Toast.makeText(this, "You win!", LENGTH_SHORT).show(); } else { Toast.makeText(this, "Try again", LENGTH_SHORT).show(); } }
自定义View可以绑定自己的侦听器但是不用指定一个id。
public class MyButton extends Button { @OnClick public void onClick() { } }
7.重置绑定
Fragment的生命周期与Activity不同,当我们在onCreateView绑定Fragment,在onDestroyView将View 设置为null时,可以使用unbind()方法。
public class FancyFragment extends Fragment { @Bind(R.id.button1) Button button1; @Bind(R.id.button2) Button button2; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fancy_fragment, container, false); ButterKnife.bind(this, view); return view; } @Override public void onDestroyView() { super.onDestroyView(); ButterKnife.unbind(this); } }
8.可选绑定
默认情况下,”@Bind”和”@OnClick”(或者其他监听)监听绑定都是必需的。如果不能找到目标视图,则会引发异常。
为了制止这种行为,创建一个可选的结合,添加一个‘@Nullable’注解字段或方法。
任何名字为@Nullable的注解可以被这样使用。鼓励你使用Android自己的注解库”support-annotations”中的@Nullable注解,参见Android Tools Project.
@Nullable @Bind(R.id.might_not_be_there) TextView mightNotBeThere; @Nullable @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() { }
9.多元监听
与方法注解相匹配的监听器有多个回调可以被用来绑定在他们中间的任何一个身上。每一个注解都有默认的回调跟它绑定在一起。可以使用callback参数声明一个可替代的回调。
@OnItemSelected(R.id.list_view) void onItemSelected(int position) { } @OnItemSelected(value = R.id.maybe_missing, callback = NOTHING_SELECTED) void onNothingSelected() { }
10.在Android Studio 中配置
compile ‘com.jakewharton:butterknife:7.0.1’
11.代码混淆
在代码混淆的时候可能出问题,这时候需要在当前model下的proguard-rules.pro文件做如下修改:
-keep class butterknife.** { *; } -dontwarn butterknife.internal.** -keep class **$$ViewBinder { *; } -keepclasseswithmembernames class * { @butterknife.* <fields>; } -keepclasseswithmembernames class * { @butterknife.* <methods>; }
参考:http://blog.csdn.net/i374711088/article/details/49102003