Android butterknife

作者: wongstar | 来源:发表于2017-11-25 23:04 被阅读2053次

    开发中找到xml中对应的ui并设置对应的事件,一般用findViewById,然后设置onClick事件来实现,这样写起来比较麻烦,有没更简单的?Butterknife本场的主角闪亮登场.

    Butterknife作用:
    通过注解的方式来对Android View进行绑定.

    Butterknife的Github源码如下:
    https://github.com/JakeWharton/butterknife
    对它的介绍可以看下面链接:
    http://jakewharton.github.io/butterknife/

    下面根据文档描述,简单的介绍下如何使用:

    • 注解实例变量view 取代findViewById
    class ExampleActivity extends Activity {
      @BindView(R.id.title) 
      TextView title;//取代findViewByid(R.id.title)
      @BindView(R.id.subtitle) 
      TextView subtitle;//取代findViewByid(R.id.subtitle)
      @BindView(R.id.footer) 
      TextView footer;//取代findViewByid(R.id.footer)
    
      @Override public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.simple_activity);
        ButterKnife.bind(this);//注意这里必须设置绑定当前Activity
        // TODO Use fields...
       //后续就可以直接使用比如
       title.setText("Just test");
      }
    }
    

    上面代码在butterknife内部生产类似下面的code

    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);
    }
    
    • 对资源绑定注解
      在Butterknife中定义如下对资源的注解
      @BindBool, @BindColor, @BindDimen, @BindDrawable, @BindInt, @BindString 上面的可以对应获取android res目录下对应的资源。
      举个🌰:
    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中如何使用butterknife
    1. bind对应的view通过它们的root view,举个例子在Fragment中
    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);//注意这里传入的是root view
        // TODO Use fields...
        return view;
      }
    }
    

    或者是在ViewHolder中使用

    static class ViewHolder {
        @BindView(R.id.title) TextView name;
        @BindView(R.id.job_title) TextView jobTitle;
    
        public ViewHolder(View view) {
          ButterKnife.bind(this, view);//这里对应的是bind(this,view)
        }
      }
    
    • 绑定View List
    @BindViews({ R.id.first_name, R.id.middle_name, R.id.last_name })
    List<EditText> nameViews;
    
    • 绑定View的事件
      对应View onClick事件
    @OnClick(R.id.submit)
    public void submit(View view) {//其中submit方法中的参数是可选的
      // TODO submit data to server...
    }
    

    对应ViewOnItemSelected事件

    @OnItemSelected(R.id.list_view)
    void onItemSelected(int position) {
      // TODO ...
    }
    

    当然也可以多个view对应一个click事件如下:

    @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的绑定事件更简单如下:

    public class FancyButton extends Button {
      @OnClick
      public void onClick() {
        // TODO do something!
      }
    }
    
    • 释放对应的bind资源
    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();//在onDestoryView中释放对应的资源
      }
    }
    
    • 其他较为少用的方法
    TextView firstName = ButterKnife.findById(view, R.id.first_name);
    //替换findViewById 不需要强转
    //The apply method allows you to act on all the views in a list at once
    ButterKnife.apply(nameViews, DISABLE); //马上设置
    ButterKnife.apply(nameViews, ENABLED, false);//设置
    

    遇到版本问题,具体如下

        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            LogUtil.d("onCreate........................");
            myLocationListener = new MyLocationListener(getLifecycle());
            setContentView(R.layout.lifecycle_test);
            ButterKnife.bind(this);
        }
    
        @OnClick(R.id.btnJump)
        public void onClick(View view){
            Intent intent = new Intent(this, DatabaseStudyActivity.class);
            startActivity(intent);
        }
    

    发现点击Button无法响应对应的onClick时间,什么原因呢?google了下发现是build.grandle配置出现了问题,下面是build.gradle中的配置

        implementation 'com.jakewharton:butterknife:8.8.1'
        implementation 'com.jakewharton:butterknife-annotations:8.8.1'
    

    ButterKnife从7.x到8.x后,运行时和编译器被分开来了,所以需要加入compiler在build.grandle中,如下所示:

    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    

    这样整个build.gradle配置如下:

        implementation 'com.jakewharton:butterknife:8.8.1'
        implementation 'com.jakewharton:butterknife-annotations:8.8.1'
        annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    

    相关文章

      网友评论

      本文标题:Android butterknife

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