Android学习笔记- ButterKnife 8.0注解使用介绍

前言:

App项目开发大部分时候还是以UI页面为主,这时我们需要调用大量的findViewById以及setOnClickListener等代码,控件的少的时候我们还能接受,控件多起来有时候就会有一种想砸键盘的冲动。所以这个时候我们想着可以借助注解的方式让我们从这种繁重的工作中脱离出来,也让代码变得更加简洁,便于维护,今天主要学习一下只专注View、Resource、Action注解框架ButterKnife。

ButterKnife介绍

ButterKnife是一个专注于Android系统的View、Resource、Action注入框架。

官网:http://jakewharton.github.io/butterknife/

gitHub:https://github.com/JakeWharton/butterknife/

ButterKnife使用前后对比:

看看没有使用View注解之前我们是如何做的

1.)使用之前
public class ExampleActivity extends AppCompatActivity {
    private final static String TAG = ExampleActivity.class.getSimpleName();
    String butterKnifeStr;
    Drawable butterKnifeDrawable;
    Button butterKnifeBtn;
    ImageView butterKnifeIv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_butter_knife);
        initResource();
        initViews();
    }

    private void initViews() {
        butterKnifeBtn = (Button) findViewById(R.id.btn_butter_knife);
        butterKnifeBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "onButterKnifeBtnClick");
            }
        });
        butterKnifeIv = (ImageView) findViewById(R.id.iv_butter_knife);
        butterKnifeBtn.setText(butterKnifeStr);
        butterKnifeIv.setImageDrawable(butterKnifeDrawable);
    }

    private void initResource() {
        butterKnifeStr = getString(R.string.title_btn_butter_knife);
        butterKnifeDrawable = getDrawable(R.mipmap.ic_launcher);
    }
}
2.)使用之后
public class ButterKnifeActivity extends AppCompatActivity {
    private final static String TAG = ButterKnifeActivity.class.getSimpleName();
    private Unbinder unbinder;
    @BindString(R.string.title_btn_butter_knife)
    String butterKnifeStr;
    @BindDrawable(R.mipmap.ic_launcher)
    Drawable butterKnifeDrawable;
    @BindView(R.id.btn_butter_knife)
    Button butterKnifeBtn;
    @BindView(R.id.iv_butter_knife)
    ImageView butterKnifeIv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_butter_knife);
        unbinder = ButterKnife.bind(this);
        initViews();
    }

    private void initViews() {
        butterKnifeBtn.setText(butterKnifeStr);
        butterKnifeIv.setImageDrawable(butterKnifeDrawable);
    }

    @OnClick(R.id.btn_butter_knife)
    public void onButterKnifeBtnClick(View view) {
        Log.e(TAG, "onButterKnifeBtnClick");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbinder.unbind();
    }
}
3.)ButterKnife 优势

通过上面使用前后对比来分析下ButterKnife优势

  • 强大的View绑定和Click事件处理功能,简化代码,提升开发效率
  • 方便的处理Adapter里的ViewHolder绑定问题
  • 运行时不会影响APP效率,使用配置方便
  • 代码清晰,可读性强

使用前后对比之后有没有觉得非常的简单易用。接下来来看下具体怎么使用的?

ButterKnife如何使用:

1.)在Project的build.gradle中添加如下配置
buildscript {
  repositories {
    mavenCentral()
   }
  dependencies {
    classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8‘
  }
}
2.)在Module的build.gradle添加如下配置
apply plugin: ‘com.neenbedankt.android-apt‘

android {
  ...
}

dependencies {
  compile ‘com.jakewharton:butterknife:8.1.0‘
  apt ‘com.jakewharton:butterknife-compiler:8.1.0‘
}
3.)注入和重置注入

Activity

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...
  }
}

Fragment:由于不同的视图生命周期,所以需要在onCreateView bind,在onDestroyView 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();
  }
}

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);
    }
  }
}
4.)view注入 @BindView,@BindViews
 @BindView(R.id.btn_butter_knife)
    Button butterKnifeBtn;
    @BindViews({R.id.tv_butter_knife1,R.id.tv_butter_knife2,R.id.tv_butter_knife3})
    List<TextView> textViews;
5.)Resource注入
 @BindString(R.string.title_btn_butter_knife)
    String butterKnifeStr;//string注解使用
    @BindDrawable(R.mipmap.ic_launcher)
    Drawable butterKnifeDrawable;//Drawable注解使用
    @BindBitmap(R.mipmap.ic_launcher)
    Bitmap  butterKnifeBitmap;;//Bitmap注解使用
    @BindArray(R.array.day_of_week)
    String weeks[];//数组
    @BindColor(R.color.colorPrimary)
    int colorPrimary;//color注解使用
    @BindDimen(R.dimen.activity_horizontal_margin)
    Float spacer;
6.)单事件注入

一个控件指定一个事件回调

    /**
     * 带参数
     */
    @OnClick(R.id.btn_butter_knife)
    public void onButterKnifeBtnClick() {
    }

    /**
     * 带参数
     */
    @OnClick(R.id.btn_butter_knife)
    public void onButterKnifeBtnClick(View view) {
        Log.e(TAG, "onButterKnifeBtnClick");
    }

    /**
     * 带参数
     * @param button
     */
    @OnClick(R.id.btn_butter_knife)
    public void onButterKnifeBtnClick(Button button) {
        Log.e(TAG, "onButterKnifeBtnClick");
    }

也可以多个控件指定一个事件回调

   /**
     * 两个不同的button都相应onButterKnifeBtnClick事件回调
     *
     * @param button
     */
    @OnClick({R.id.btn_butter_knife, R.id.btn_butter_knife1})
    public void onButterKnifeBtnClick(Button button) {
        Log.e(TAG, "onButterKnifeBtnClick");
    }

自定义的控件不通过ID也可以绑定到自己的事件

public class FancyButton extends Button {
  @OnClick
  public void onClick() {
    // TODO do something!
  }
}
7.)多事件回调

有一些View的listener是有多个回调方法的,比如EditText添加addTextChangedListener

editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

可以使用注解方式改成如下

 @OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.BEFORE_TEXT_CHANGED)
    void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }
    @OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.TEXT_CHANGED)
    void onTextChanged(CharSequence s, int start, int before, int count) {

    }
    @OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
    void afterTextChanged(Editable s) {

    }
8.)选择性注入

默认情况下,@Bind 和listener的注入都是必须的,如果target view没有被发现,则会报错. 为了抑制这种行为,可以用@Optional注解来标记field和方法,让注入变成选择性的,如果targetView存在,则注入, 不存在,则什么事情都不做.或者使用 Android‘s "support-annotations" library.中的@Nullable来修饰

@Nullable @BindView(R.id.might_not_be_there)
TextView mightNotBeThere;

@Optional @OnClick(R.id.maybe_missing)
void onMaybeMissingClicked() {
  // TODO ...
}
9.)ButterKnife.apply()函数

可以通过ButterKnifeapply()函数对view集合元素或者单个view的Action, Setter和Property进行修改

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

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

ButterKnife.apply(nameViews, View.ALPHA, 0.0f);
10.)ButterKnife.findById()

ButterKnife 也提供了findById函数,通过findById()可以获取Activity、Dialog、View中的view,并且是泛型类型不需要强转

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

ButterKnife自动生成插件安装:

在AndroidStudio->File->Settings->Plugins->搜索Zelezny下载添加就行 ,可以快速生成对应组件的实例对象,不用手动写。使用时,在要导入注解的Activity 或 Fragment 或 ViewHolder的layout资源代码上,右键——>Generate——Generate ButterKnife Injections,然后就出现如图的选择框。

插件gitHub地址:https://github.com/avast/android-butterknife-zelezny

下面给了一个使用流程图

参考链接:http://www.cnblogs.com/whoislcj/p/5620128.html

     http://jakewharton.github.io/butterknife/javadoc/

时间: 2024-12-10 01:26:05

Android学习笔记- ButterKnife 8.0注解使用介绍的相关文章

Android学习笔记——关于onConfigurationChanged

从事Android开发,免不了会在应用里嵌入一些广告SDK,在嵌入了众多SDK后,发现几乎每个要求在AndroidManifest.xml申明Activity的广告SDK都会要求加上注明这么一句属性: android:configChanges="orientation|keyboard|keyboardHidden" 通过查阅Android API可以得知android:onConfigurationChanged实际对应的是Activity里的onConfigurationChan

Pro Android学习笔记(三三):Menu(4):Alternative菜单

什么是Alternative menu(替代菜单) 举个例子,Activity显示一个文本文件.如果用户想对文本文件进行编辑,Activity不提供编辑能力,但可由其他activity或者其他应用提供.我们将相关信息存储在一个intent中,例如该文本的Uri.这个intent可以匹配系统的多个应用,替代菜单将这些应用一一列出,菜单项的title就是该可被调用的activity的名字,图标也为该可被调用的activity的图表. 小例子说明 我们通过一个小例子进行学习,简单地打开一个URL:we

Android学习笔记(二二): 多页显示-Tag的使用

在手机屏幕中,Tab也是比较常用的,通常和List结合,例如我们手机的通信录.下面是Tag的结构. TabHost是整个Tab的容器,包括两部分,TabWidget和FrameLayout.TabWidget就是每个tab的标签,FrameLayout则是tab内容. 如果我们使用extends TabAcitivty,如同ListActivity,TabHost必须设置为@android:id/tabhost TabWidget必须设置android:id为@android:id/tabs F

android学习笔记——利用BaseAdapter生成40个列表项

RT: main.xml ? 1 2 3 4 5 6 7 8 9 10 11 12 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"               android:orientation="vertical"        

udacity android 学习笔记: lesson 4 part b

udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 联系:1307316一九六八 声明:本文採用下面协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 ,转载请注明作者及出处. tips:https://code.csdn.net/titer1/pat_aha/blob/master/Mar

Pro Android学习笔记(二九):用户界面和控制(17):include和merge

xml控件代码重用:include 如果我们定义一个控件,需要在不同的layout中重复使用,或者在同一个layout中重复使用,可以采用include的方式.例如定义my_button.xml如下 <?xml version="1.0" encoding="utf-8"?> <Button xmlns:android="http://schemas.android.com/apk/res/android"     androi

Pro Android学习笔记(十二):了解Intent(下)

解析Intent,寻找匹配Activity 如果给出component名字(包名.类名)是explicit intent,否则是implicit intent.对于explicit intent,关键就是component 名字,在<intent-fliter>中声明的其他属性被忽略.对于implicit intent,则根据action,category和data来进行匹配.然而一个intent fliter中可以声明多个actions,多个categories,多个data属性,因此可以满

Pro Android学习笔记(十):了解Intent(上)

Android引入了Intent的概念来唤起components,component包括:1.Activity(UI元件) 2.Service(后台代码) 3.Broadcast receiver(处理广播消息的代码) 4.Content provider(抽象数据的代码) Intent基本含义 intent是通知平台处理(唤起)的动作.Android唤起的动作将取决于注册了什么动作.例如我们有个简单的Activity:IntentBaiscViewActivity.在AndroidManife

Android学习笔记(三九):资源resource(下)

在上一次学习笔记中,学习了XML文件的解析,实际上一些简单的activity属性,一些简单的信息,我们也可以放入xml文件中,可以直接放入res/vaules,由系统来进行解析,而无须使用XmlPullParser来自己分析. Dimension 用于字体大小,间距pading等等.常用的尺寸大小详细见Android 学习笔记(十四):Activity-AutoCompleteTextView,一般我们使用dip/dp和sp,因为和in(inch),mm,以及px(像素点)不同,它和物理屏幕尺寸