Android 框架之ButterKnife

作者: 王世军Steven | 来源:发表于2017-03-03 09:29 被阅读79次

    ButterKnife 是一个Android系统的View注入框架 , 使用它我们再也不用写大量的findViewById 和 setOnClickListener 等代码 . 即使真有使用findViewById的需要也是可以省略强制类型转换 . 所有这个框架真的是很好 .

    简单使用

    正常情况下我们绑定控件使用findViewById方式如下.

    class ExampleActivity extends Activity {
      TextView title;
      TextView subtitle;
      TextView footer;
    
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.simple_activity);
        // 绑定控件 
        title = (TextView)findViewById(R.id.title);
        subtitle = (TextView)findViewById(R.id.subtitle);
        footer = (TextView)findViewById(R.id.footer);
      }
    }
    

    如果们使用ButterKnife代码如下.

    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);
        // 绑定这个Activity,这是必须的否则无法实现绑定控件.和其他操作.
        ButterKnife.bind(this);
        // TODO Use fields...
      }
    }
    

    从上面可以看出我们只需要注解进行绑定即可.省略了大量的findViewById的代码.

    配置ButterKnife(8.4.0 版本)

    • 安装ButterKnife插件.


      ButterKnife 插件
    • 配置 build.gradle 文件

      • Module的build.gradle添加如下依赖.
      compile 'com.jakewharton:butterknife:8.4.0'
      annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
      
    配置一
    • 在项目的build.gradle 中添加如下代码
    classpath 'com.jakewharton:butterknife-gradle-plugin:8.4.0'
    
    配置二

    同步项目即可正常是用ButterKnife.

    资源绑定

    使用ButterKnife的@Bindxxx系列注解(xxx 代表资源类型如 : bool, int, drawable 等)可以绑定预先定义好的资源.

    class ExampleActivity extends Activity {
      @BindString(R.string.title) String title;
      @BindDrawable(R.drawable.ic_header) Drawable ic_header;
      @BindColor(R.color.black) int black; 
      @BindDimen(R.dimen.size) Float spacer; 
      @BindInt(R.int.number) Integer number;
    }
    

    绑定Fragment中的控件.

    通过绑定自定义View可以实现绑定任意对象

    // Fragment 中的控件的绑定.
    public class MyFragment 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;
      }
    }
    

    简化ListView中的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("ButterKnife 绑定了.");
        // ...
        return view;
      }
    
      static class ViewHolder {
        @BindView(R.id.title) 
        TextView name;
        @BindView(R.id.text) 
        TextView text;
    
        public ViewHolder(View view) {
          ButterKnife.bind(this, view);
        }
      }
    }
    

    绑定一组View到一个List或者Array中.

    // 绑定三个控件到List中.
    @BindViews({ R.id.first_view, R.id.second_view, R.id.third_view })
    List<EditText> mViews;
    

    使用 ButterKnife的apply 方法可以设置上面集合中的View属性.

    // 将三个View都设置成Disable
    ButterKnife.apply(mViews, DISABLE);
    // 将三个View都设置成不可点击.
    ButterKnife.apply(mViews, ENABLED, false);
    

    使用Action 和 Setter 接口.

    使用Action和Setter接口可以定义一些行为.

    // 使用Action接口定义DISABLE的行为.
    static final ButterKnife.Action<View> DISABLE = new ButterKnife.Action<View>() {
      @Override public void apply(View view, int index) {
        view.setEnabled(false);
      }
    };
    // 使用Setter接口定义ENABLED的行为.
    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);
      }
    };
    

    设置任意属性

    // 设置所有View的透明度.
    ButterKnife.apply(mViews, View.ALPHA, 0.0f);
    

    绑定 listener

    使用@OnClick注解可以绑定点击事件,关于绑定方法有如下几种形式

    • 没有参数 : 如果不需要操作控件可以不带参数
    // 省略参数
    @OnClick(R.id.btn)
    public void btnClicked() {
      // do something
    }
    
    • 带有一个参数 : 可以View ,也可以是具体的类型比如Button.
    // 绑定按钮的点击事件
    @OnClick(R.id.btn)
    public void btnClicked(View view) {
      // do something
    }
    // 直接指定类型.
    @OnClick(R.id.btn)
    public void btnClicked(Button view) {
      // do something
    }
    
    • 绑定多个控件到同一个方法上.
    // 指定多个控件的到同一个方法上
    @OnClick({R.id.btn,R.id.btn2,R.id.btn3})
    public void btnClicked(View view) {
      // do something
    }
    
    • 自定义控件可以直接绑定自身的Listener,不用指定ID
    public class MyButton extends Button {
      @OnClick
      public void onClick() {
        // do something!
      }
    }
    

    取消绑定

    ButterKnife在绑定时会返回一个Unbinder对象可以使用它来解除绑定.

    public class MyFragment 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();
      }
    }
    

    处理异常

    ButterKnife 在绑定控件是如果没有找到个指定的控件,则会抛出异常, 可以使用@Nullable 和 @optional注解来解决.

    // 绑定控件使用@Nullable
    @Nullable 
    @BindView(R.id.btn) 
    TextView btn;
    // 绑定Listener , @Optional 
    @Optional 
    @OnClick(R.id.btn) 
    void onBtnClicked() {
      // TODO ...
    }
    

    Item点击事件绑定.

    // ListView Item 点击事件绑定
    @OnItemSelected(R.id.list_view)
    void onItemSelected(int position) {
      // TODO ...
    }
    // 绑定两个.Item的listener
    @OnItemSelected(value = R.id.maybe_missing, callback = NOTHING_SELECTED)
    void onNothingSelected() {
      // TODO ...
    }
    

    findById 方法

    使用findById可以和findViewById用法一样,但是ButterKnife会自动进行类型转化.

    View view = LayoutInflater.from(context).inflate(R.layout.thing, null);
    TextView firstName = ButterKnife.findById(view, R.id.first_name);
    TextView lastName = ButterKnife.findById(view, R.id.last_name);
    ImageView photo = ButterKnife.findById(view, R.id.photo);
    

    OK ButterKnife 8.4.0 简单使用结束.

    相关文章

      网友评论

        本文标题:Android 框架之ButterKnife

        本文链接:https://www.haomeiwen.com/subject/hkdlgttx.html