ButterKnifey的GitHub地址为https://github.com/JakeWharton/butterknife/
配置参考GitHub地址,如下:
在你的project的build.gradle中配置android-apt插件,内容如下:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
然后再你的module中应用你刚刚添加的插件,内容如下:
apply plugin: 'com.neenbedankt.android-apt'
android {
...
}
dependencies {
compile 'com.jakewharton:butterknife:8.4.0'
apt 'com.jakewharton:butterknife-compiler:8.4.0'
}
Library projects
如果你要在你的库项目中使用ButterKnifey,请在你的buildscript 中添加插件:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.jakewharton:butterknife-gradle-plugin:8.4.0'
}
}
然后在你的module中应用插件:
apply plugin: 'com.android.library'
apply plugin: 'com.jakewharton.butterknife'
然后,现在请在所有的ButterKnifey的声明中,用R2代替R,如:
class ExampleActivity extends Activity {
@BindView(R2.id.user) EditText username;
@BindView(R2.id.pass) EditText password;
...
}
常用功能:
1、使用@BindView代替findViewById(ButterKnife v6.1.0之前是使用@InjectView) ,如:
mTextView1 = (TextView) findViewById(R.id.butter_text_view_1);
可以这样实现:
@BindView(R.id.butter_text_view_1)
TextView mTextView1;
如果id找不到,会在编译的时候报错的。
Activity:
通常,我们在设置好布局之后调用ButterKnife.bind(this);,即必须在setContentView();之后,且父类bind绑定后,子类不需要再bind,如
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo_butter_knife);
//using butter knife
ButterKnife.inject(this);
}
注意,需要在onDestroy()时解绑:
@Override
protected void onDestroy() {
super.onDestroy();
ButterKnife.unbind(this);//解除绑定,官方文档只对fragment做了解绑
}
Fragment:
与Activity不同的是,Fragment中需要传入一个View,ButterKnife.bind(this, mRootView); 如:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_simple, container, false);
ButterKnife.bind(this, view);
return view;
}
注意,需要在onDestroyView() 时解绑:
@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.unbind(this);//解绑
}
需要注意的是View变量声明的时候不能为private或者static.
还可以用来简化Adapter里面的ViewHolder: 具体参考https://github.com/gindoc/AndroidButterKnifeSample/blob/master/app/src/main/java/com/example/mengdd/butterknifesample/data/PersonAdapter.java
,如:
public class TestAdapter extends BaseAdapter {
private List<String> list;
private Context context;
public TestAdapter(Context context, List<String> list) {
this.list = list;
this.context = context;
}
@Override
public int getCount() {
return list==null ? 0 : list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.layout_list_item, null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textview.setText("item=====" + position);
return convertView;
}
static class ViewHolder {
@Bind(R.id.hello_world)
TextView textview;
public ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
}
2、绑定资源,如
@BindString(R.string.app_name)
String appName;//sting
@BindColor(R.color.red)
int textColor;//颜色
@BindDrawable(R.mipmap.ic_launcher)
Drawable drawable;//drawble
@Bind(R.id.imageview)
ImageView mImageView;
@Bind(R.id.checkbox)
CheckBox mCheckBox;
@BindDrawable(R.drawable.selector_image)
Drawable selector;
3、绑定点击事件,监听方法的参数是可选的,如:
- v直接绑定一个方法(有参)
@OnClick(R.id.submit)
public void submit(View view) {
// TODO submit data to server...
}
- 直接绑定一个方法(无参)
@OnClick(R.id.submit)
public void submit() {
// TODO submit data to server...
}
- 参数是一个特定的类型,它将自动被转换
@OnClick(R.id.submit)
public void sayHi(Button button) {
button.setText("Hello!");
}
- 多个view统一处理同一个点击事件
@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 FancyButton extends Button {
@OnClick
public void onClick() {
// TODO do something!
}
}
- 添加多回调方法的监听的使用方法,如 给EditText加addTextChangedListener,利用callback指定回调方法,实现想回调的方法即可,(哪个注解不会用点进去看下源码)
@OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.BEFORE_TEXT_CHANGED)
void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.TEXT_CHANGED)
void onTextChanged(CharSequence s, int start, int before, int count) {
}
@OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
void afterTextChanged(Editable s) {
}
方法注解可以用来绑定到这些方法中的任何一个.
每一个注解有一个默认的callback,指定它绑定到什么方法上;可以通过callback参数指定为一个特定的方法.
比如,(此处用Spinner的onItemSelectedListener举例):
mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
没有指定callback,默认对应onItemSelected()方法:
@OnItemSelected(R.id.my_spinner)
//default callback : ITEM_SELECTED
void onItemSelected(int position) {
Toast.makeText(this, "position: " + position, Toast.LENGTH_SHORT).show();
}
指定了callback,对应onNothingSelected()方法:
@OnItemSelected(value = R.id.my_spinner, callback = OnItemSelected.Callback.NOTHING_SELECTED)
void onNothingSelected() {
Toast.makeText(this, "Nothing", Toast.LENGTH_SHORT).show();
}
- 对一组View进行统一操作
a.装入一个list,如
@Bind({ R.id.first_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;
b.设置统一处理
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);
}
};
c.统一操作处理,例如设置是否可点,属性等
ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);
apply()方法允许你为一组对象批量地设置值.
apply()方法共有3种形式:
public static <T extends View> void apply(List<T> list, Action<? super T> action)
public static <T extends View, V> void apply(List<T> list, Setter<? super T, V> setter, V value)
public static <T extends View, V> void apply(List<T> list, Property<? super T, V> setter, V value)
即Action, Setter和Property三种.
其中Action和Setter都是ButterKnife的类,需要继承,写自己的子类实现,然后传入对象.
Setter的第三个参数可以指定要set到什么值.
Property是Android中的类:https://developer.android.com/reference/android/util/Property.html
- 可选绑定:默认情况下,“绑定”和“监听”绑定都是必需的。如果不能找到目标视图,则将抛出异常。所以做空处理
@Nullable @Bind(R.id.might_not_be_there) TextView mightNotBeThere;
@Nullable @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {
// TODO ...
}
之前的版本v6.1.0用的是@Optional?
选择性注入(Optional Injection):
默认情况下,@InjectView和listener的注入都是必须的,如果target view没有被发现,则会报错.
为了抑制这种行为,可以用@Optional注解来标记field和方法,让注入变成选择性的,如果targetView存在,则注入, 不存在,则什么事情都不做.
当布局被复用时,这个@Optional注解很有用.
代码混淆
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
}
Zelezny插件的使用
在AndroidStudio->File->Settings->Plugins->搜索Zelezny下载添加就行,如图:
安装好后需要restart你的Android Studio。
在使用此插件前,需要已经导入了butterknife的jar(或者在build.gradle中已经加入:compile’com.jakewharton:butterknife:7.0.0’)
随后,在你需要导入注解的Activity或者Fragment或者ViewHolder的layout资源代码上,右击,选择 Generate 然后Generate ButterKnife Injections,这时候生成类似于下列的选择框:
Element为view的类型,ID为layout中资源的id名字,Variable Name即为你在代码中引用出来的变量名,点击Confirm后即可。
下面是Android ButterKnife Zelezny的github上的一个动态使用流程图:
以上例子,fork自https://github.com/mengdd/AndroidButterKnifeSample
以上文章参考:
http://blog.csdn.net/itjianghuxiaoxiong/article/details/50177549
http://www.cnblogs.com/mengdd/p/4595973.html
http://www.cnblogs.com/soaringEveryday/p/4607438.html?utm_source=tuicool&utm_medium=referral