有用的资料

GitHub地址:https://github.com/JakeWharton/butterknife
ButterKnife文档:http://jakewharton.github.io/butterknife/

在Android Studio中引入ButterKnife

  • 配置build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}

apply plugin: 'com.neenbedankt.android-apt'

dependencies {
compile 'com.jakewharton:butterknife:8.0.1'
apt 'com.jakewharton:butterknife-compiler:8.0.1'
}
  • 添加支持lint warning 检查机制

    lintOptions {
    disable 'InvalidPackage'
    }
  • 防止与dagger-compiler冲突

    packagingOptions {
    exclude 'META-INF/services/javax.annotation.processing.Processor'
    }
  • 添加混淆配置

    -keep class butterknife.** { *; }
    -dontwarn butterknife.internal.**
    -keep class **$$ViewBinder { *; }
    -keepclasseswithmembernames class * {
    @butterknife.* <fields>;
    }
    -keepclasseswithmembernames class * {
    @butterknife.* <methods>;
    }

    有了上述的准备工作就可以使用BufferKnife了:

View绑定

很简单只需要使用@BindView后面紧跟着View的id,在onCreate方法中使用ButterKnife.bind进行绑定即可。但是需要注意的是对于绑定的成员变量不能是private,或者static的否则会出现:

@Bind fields must not be private or static. …

class ExampleActivity extends Activity {
@BindView(R.id.title) TextView title;
@BindView(R.id.subtitle) TextView subtitle;
@BindView(R.id.footer) TextView footer;

@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.bind(this);
// TODO Use fields...
}
}

资源绑定

class ExampleActivity extends Activity {
@BindString(R.string.title) String title;
@BindDrawable(R.drawable.graphic) Drawable graphic;
@BindColor(R.color.red) int red; // int or ColorStateList field
@BindDimen(R.dimen.spacer) Float spacer; // int (for pixel size) or float (for exact value) field
// ...
}

非Activity的绑定

public class FancyFragment extends Fragment {
@BindView(R.id.button1) Button button1;
@BindView(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);
// TODO Use fields...
return view;
}
}

绑定Adapter中ViewHolder

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("John Doe");
// etc...

return view;
}

static class ViewHolder {
@BindView(R.id.title) TextView name;
@BindView(R.id.job_title) TextView jobTitle;

public ViewHolder(View view) {
ButterKnife.bind(this, view);
}
}
}

绑定监听器

单击事件绑定:

@OnClick(R.id.submit)
public void submit(View view) {
// TODO submit data to server...
}

多个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!
}
}

取消绑定

我们可能需要在Fragment销毁的时候将绑定的View全部设置为null,ButterKnife提供了一个unbind方法自动执行这个操作。

public class FancyFragment extends Fragment {
@BindView(R.id.button1) Button button1;
@BindView(R.id.button2) Button button2;
private Unbinder unbinder;

@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fancy_fragment, container, false);
unbinder = ButterKnife.bind(this, view);
// TODO Use fields...
return view;
}

@Override public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}

可选绑定

默认情况下对于使用 @Bind绑定View或者使用onClick绑定事件的时候这个View都必须存在,如果不存在将会抛出错误,但是我们有可能会遇到Target View不存在的情况,这时候就需要用到@Nullable 和@Optional 了,其中前者用于修饰成员变量,后者用于修饰方法。

@Nullable @BindView(R.id.might_not_be_there) TextView mightNotBeThere;
@Optional @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {
// TODO ...
}

View List批量操作

如果我们有一系列的View放到了一个List里面,就可以进行批量操作了:批量绑定,批量设置属性等。

@BindViews({ R.id.first_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;

使用apply方法可以允许将Action立刻应用到View list 上。

ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);

下面是对应的Setter以及Action的定义:

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);
}
};

apply方法还可以用于将Android 属性应用到View数组中:

ButterKnife.apply(nameViews, View.ALPHA, 0.0f);
Contents
  1. 1. 有用的资料
  2. 2. 在Android Studio中引入ButterKnife
  3. 3. View绑定
  4. 4. 资源绑定
  5. 5. 非Activity的绑定
  6. 6. 绑定Adapter中ViewHolder
  7. 7. 绑定监听器
  8. 8. 取消绑定
  9. 9. 可选绑定
  10. 10. View List批量操作