(4.2.27)Butter Knife 基本用法

View Binding

在 Android 开发中,常常需要写很多视图绑定的代码,比如:

1
TextView textView = (TextView) findViewById(R.id.textview);

在视图组件少的时候还好,当布局文件中包含有大量的视图时,这将是不小的工作量啊,而且会让 Activity 的代码看起来非常臃肿,不简洁,不好看,这时,Butter Knife 可以帮助我们来做这件重复性的劳动:

1
2
3
4
5
6
7
8
9
10
11
12
class ExampleActivity extends Activity {
  @Bind(R.id.title) TextView title;
  @Bind(R.id.subtitle) TextView subtitle;
  @Bind(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...
  }
}

这样,我们就不需要再频繁的写 findViewById 了,另外,官网上提到这个:

Instead of slow reflection, code is generated to perform the view look-ups. Calling bind delegates to this generated code that you can see and debug.

Java基础太差,所以上面这段话的意思领会的不是很清楚,猜想应该是说 Butter Knife 实现的机制不是影响性能的反射方式,而是通过视图的循环绑定实现,上面的代码其实是这样的:

1
2
3
4
5
public void bind(ExampleActivity activity) {
  activity.subtitle = (android.widget.TextView) activity.findViewById(2130968578);
  activity.footer = (android.widget.TextView) activity.findViewById(2130968579);
  activity.title = (android.widget.TextView) activity.findViewById(2130968577);
}

看起来,实际运行的效率和自己写 findViewById 是一样的。

Resource Binding

原来 Butter Knife 还可以绑定资源, @BindBool@BindColor、 @BindDimen@BindDrawable@BindInt@BindString,这是要省多少事儿啊!

1
2
3
4
5
6
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
  // ...

Non-Activity Binding

除了支持 Activity ,Butter Knife 其实是可以将视图绑定到任何的对象上去,比如说另外一个经常用到的组件 Fragment :

1
2
3
4
5
6
7
8
9
10
11
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);
    // TODO Use fields...
    return view;
  }
}

但是这里需要注意的是 Fragment 和 Activity 有着不同的生命周期,当在 onCreateView 中将视图绑定到 Fragment 中时,需要在 onDestroyView 方法中解绑定:

1
2
3
4
@Override public void onDestroyView() {
  super.onDestroyView();
  ButterKnife.unbind(this);
}

还有一个很常用的组件ListView, 现在可能慢慢被 RecyclerView 取代,但他们都是使用ViewHolder 来绑定视图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 {
    @Bind(R.id.title) TextView name;
    @Bind(R.id.job_title) TextView jobTitle;

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

简单来说,就是需要使用 findViewById 方法的地方都可以用 ButterKnife.bind 来替代。

View List

肯定会有这样的时候,我们需要把一组视图添加到一个数组中进行统一设置,同样的,Butter Knife 也可以这样使用:

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

通过 apply 方法还可以直接对数组中的视图属性进行操作:

1
2
3
ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED, false);
ButterKnife.apply(nameViews, View.ALPHA, 0.0f);

Listener Binding

一般设置按钮的监听事件时,需要这样写:

1
2
3
4
5
6
button.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View v) {
                
  }
});

Button Knife 简化后:

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

方法中的参数也是可选的:

1
2
3
4
5
6
7
8
9
@OnClick(R.id.submit)
public void submit() {
  // TODO submit data to server...
}

@OnClick(R.id.submit)
public void sayHi(Button button) {
  button.setText("Hello!");
}

甚至多个视图 ID 绑定到同一个事件处理方法中:

1
2
3
4
5
6
7
8
@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();
  }
}

Summary

上面提到的 Butter Knife 的使用方法都是来自于官方文档,文档还介绍了其它的一些用法,因为自己不是太懂所以没有全部列出了,有需要请直接参考官方文档。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值