查看: 467|回复: 0

[手机开发] Android注解使用之ButterKnife 8.0详解

发表于 2017-11-27 08:00:06
句号论坛

前言:

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.)使用之前

  1. public class ExampleActivity extends AppCompatActivity {
  2. private final static String TAG = ExampleActivity.class.getSimpleName();
  3. String butterKnifeStr;
  4. Drawable butterKnifeDrawable;
  5. Button butterKnifeBtn;
  6. ImageView butterKnifeIv;
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_butter_knife);
  11. initResource();
  12. initViews();
  13. }
  14. private void initViews() {
  15. butterKnifeBtn = (Button) findViewById(R.id.btn_butter_knife);
  16. butterKnifeBtn.setOnClickListener(new View.OnClickListener() {
  17. @Override
  18. public void onClick(View v) {
  19. Log.e(TAG, "onButterKnifeBtnClick");
  20. }
  21. });
  22. butterKnifeIv = (ImageView) findViewById(R.id.iv_butter_knife);
  23. butterKnifeBtn.setText(butterKnifeStr);
  24. butterKnifeIv.setImageDrawable(butterKnifeDrawable);
  25. }
  26. private void initResource() {
  27. butterKnifeStr = getString(R.string.title_btn_butter_knife);
  28. butterKnifeDrawable = getDrawable(R.mipmap.ic_launcher);
  29. }
  30. }
复制代码

2.)使用之后

  1. public class ButterKnifeActivity extends AppCompatActivity {
  2. private final static String TAG = ButterKnifeActivity.class.getSimpleName();
  3. private Unbinder unbinder;
  4. @BindString(R.string.title_btn_butter_knife)
  5. String butterKnifeStr;
  6. @BindDrawable(R.mipmap.ic_launcher)
  7. Drawable butterKnifeDrawable;
  8. @BindView(R.id.btn_butter_knife)
  9. Button butterKnifeBtn;
  10. @BindView(R.id.iv_butter_knife)
  11. ImageView butterKnifeIv;
  12. @Override
  13. protected void onCreate(Bundle savedInstanceState) {
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.activity_butter_knife);
  16. unbinder = ButterKnife.bind(this);
  17. initViews();
  18. }
  19. private void initViews() {
  20. butterKnifeBtn.setText(butterKnifeStr);
  21. butterKnifeIv.setImageDrawable(butterKnifeDrawable);
  22. }
  23. @OnClick(R.id.btn_butter_knife)
  24. public void onButterKnifeBtnClick(View view) {
  25. Log.e(TAG, "onButterKnifeBtnClick");
  26. }
  27. @Override
  28. protected void onDestroy() {
  29. super.onDestroy();
  30. unbinder.unbind();
  31. }
  32. }
复制代码

3.)ButterKnife 优势

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

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

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

ButterKnife如何使用:

1).在Project的build.gradle中添加如下配置

  1. buildscript {
  2. repositories {
  3. mavenCentral()
  4. }
  5. dependencies {
  6. classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
  7. }
  8. }
复制代码

2.)在Module的build.gradle添加如下配置

  1. apply plugin: 'com.neenbedankt.android-apt'
  2. android {
  3. ...
  4. }
  5. dependencies {
  6. compile 'com.jakewharton:butterknife:8.1.0'
  7. apt 'com.jakewharton:butterknife-compiler:8.1.0'
  8. }
复制代码

3.)注入和重置注入

Activity

  1. class ExampleActivity extends Activity {
  2. @BindView(R.id.title) TextView title;
  3. @BindView(R.id.subtitle) TextView subtitle;
  4. @BindView(R.id.footer) TextView footer;
  5. @Override public void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.simple_activity);
  8. ButterKnife.bind(this);
  9. // TODO Use fields...
  10. }
  11. }
复制代码

Fragment:由于不同的视图生命周期,所以需要在onCreateView bind,在onDestroyView unbind

  1. public class FancyFragment extends Fragment {
  2. @BindView(R.id.button1) Button button1;
  3. @BindView(R.id.button2) Button button2;
  4. private Unbinder unbinder;
  5. @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  6. View view = inflater.inflate(R.layout.fancy_fragment, container, false);
  7. unbinder = ButterKnife.bind(this, view);
  8. // TODO Use fields...
  9. return view;
  10. }
  11. @Override public void onDestroyView() {
  12. super.onDestroyView();
  13. unbinder.unbind();
  14. }
  15. }
复制代码

ViewHolder

  1. public class MyAdapter extends BaseAdapter {
  2. @Override public View getView(int position, View view, ViewGroup parent) {
  3. ViewHolder holder;
  4. if (view != null) {
  5. holder = (ViewHolder) view.getTag();
  6. } else {
  7. view = inflater.inflate(R.layout.whatever, parent, false);
  8. holder = new ViewHolder(view);
  9. view.setTag(holder);
  10. }
  11. holder.name.setText("John Doe");
  12. // etc...
  13. return view;
  14. }
  15. static class ViewHolder {
  16. @BindView(R.id.title) TextView name;
  17. @BindView(R.id.job_title) TextView jobTitle;
  18. public ViewHolder(View view) {
  19. ButterKnife.bind(this, view);
  20. }
  21. }
  22. }
复制代码

4.)view注入 @BindView,@BindViews

  1. @BindView(R.id.btn_butter_knife)
  2. Button butterKnifeBtn;
  3. @BindViews({R.id.tv_butter_knife1,R.id.tv_butter_knife2,R.id.tv_butter_knife3})
  4. List<TextView> textViews;
复制代码

5.)Resource注入

  1. @BindString(R.string.title_btn_butter_knife)
  2. String butterKnifeStr;//string注解使用
  3. @BindDrawable(R.mipmap.ic_launcher)
  4. Drawable butterKnifeDrawable;//Drawable注解使用
  5. @BindBitmap(R.mipmap.ic_launcher)
  6. Bitmap butterKnifeBitmap;;//Bitmap注解使用
  7. @BindArray(R.array.day_of_week)
  8. String weeks[];//数组
  9. @BindColor(R.color.colorPrimary)
  10. int colorPrimary;//color注解使用
  11. @BindDimen(R.dimen.activity_horizontal_margin)
  12. Float spacer;
复制代码

6).单事件注入

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

  1. /**
  2. * 带参数
  3. */
  4. @OnClick(R.id.btn_butter_knife)
  5. public void onButterKnifeBtnClick() {
  6. }
  7. /**
  8. * 带参数
  9. */
  10. @OnClick(R.id.btn_butter_knife)
  11. public void onButterKnifeBtnClick(View view) {
  12. Log.e(TAG, "onButterKnifeBtnClick");
  13. }
  14. /**
  15. * 带参数
  16. * @param button
  17. */
  18. @OnClick(R.id.btn_butter_knife)
  19. public void onButterKnifeBtnClick(Button button) {
  20. Log.e(TAG, "onButterKnifeBtnClick");
  21. }
复制代码

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

  1. /**
  2. * 两个不同的button都相应onButterKnifeBtnClick事件回调
  3. *
  4. * @param button
  5. */
  6. @OnClick({R.id.btn_butter_knife, R.id.btn_butter_knife1})
  7. public void onButterKnifeBtnClick(Button button) {
  8. Log.e(TAG, "onButterKnifeBtnClick");
  9. }
复制代码

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

  1. public class FancyButton extends Button {
  2. @OnClick
  3. public void onClick() {
  4. // TODO do something!
  5. }
  6. }
复制代码

7.)多事件回调

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

  1. editText.addTextChangedListener(new TextWatcher() {
  2. @Override
  3. public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  4. }
  5. @Override
  6. public void onTextChanged(CharSequence s, int start, int before, int count) {
  7. }
  8. @Override
  9. public void afterTextChanged(Editable s) {
  10. }
  11. });
复制代码

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

  1. @OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.BEFORE_TEXT_CHANGED)
  2. void beforeTextChanged(CharSequence s, int start, int count, int after) {
  3. }
  4. @OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.TEXT_CHANGED)
  5. void onTextChanged(CharSequence s, int start, int before, int count) {
  6. }
  7. @OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
  8. void afterTextChanged(Editable s) {
  9. }
复制代码

8.)选择性注入

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

  1. @Nullable @BindView(R.id.might_not_be_there)
  2. TextView mightNotBeThere;
  3. @Optional @OnClick(R.id.maybe_missing)
  4. void onMaybeMissingClicked() {
  5. // TODO ...
  6. }
复制代码

9.)ButterKnife.apply()函数

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

  1. ButterKnife.apply(nameViews, DISABLE);
  2. ButterKnife.apply(nameViews, ENABLED, false);
  3. static final ButterKnife.Action<View> DISABLE = new ButterKnife.Action<View>() {
  4. @Override public void apply(View view, int index) {
  5. view.setEnabled(false);
  6. }
  7. };
  8. static final ButterKnife.Setter<View, Boolean> ENABLED = new ButterKnife.Setter<View, Boolean>() {
  9. @Override public void set(View view, Boolean value, int index) {
  10. view.setEnabled(value);
  11. }
  12. };
  13. ButterKnife.apply(nameViews, View.ALPHA, 0.0f);
复制代码

10.)ButterKnife.findById()

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

  1. View view = LayoutInflater.from(context).inflate(R.layout.thing, null);
  2. TextView firstName = ButterKnife.findById(view, R.id.first_name);
  3. TextView lastName = ButterKnife.findById(view, R.id.last_name);
  4. 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

上面给了一个使用流程图,不过流程图不会针对最新的8.0.1版本的,但是都是差不多的

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。



太阳http代理AD
回复

使用道具 举报

关闭

站长推荐上一条 /1 下一条