前言:

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;@Overrideprotected 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() {@Overridepublic 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;@Overrideprotected 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");}@Overrideprotected 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 {@OnClickpublic void onClick() {// TODO do something!
  }
}

7.)多事件回调

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

 editText.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {}@Overridepublic 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

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

Android注解使用之ButterKnife 8.0注解使用介绍相关推荐

  1. Android开发之注解式框架ButterKnife在ADT中的设置

    使用注解式框架ButterKnife的时候,导入到ADT中,结果项目中注解的view无效,如点击button等无任何的反应. 然后在ButterKnife的官网查看到解决办法:http://jakew ...

  2. Android项目中创建编译期的注解

    ==注解 生命周期为RetentionPolicy.RUNTIME,可在运行时通过反射获取. 生命周期为RetentionPolicy.CLASS, 编译期处理的注解,可以使用APT(Annotati ...

  3. JDK 5.0 注解的使用

    了解注解 在编写代码时,除了源程序以外,我们还会使用Javadoc标签对类.方法或成员变量进行注解,以便使用Javadoc工具生成和源代码配套的Javadoc文档. /** * 重写toString ...

  4. spring3.0注解

    使用 @Repository.@Service.@Controller 和 @Component 将类标识为 Bean Spring 自 2.0 版本开始,陆续引入了一些注解用于简化 Spring 的 ...

  5. Java-Java5.0注解解读

    概述 元注解Meta-annotation Target Retention Documented Inherited 自定义注解 定义注解格式 注解参数的可支持数据类型 实例 编写注解类 使用注解 ...

  6. Spring 3.0 注解注入详解

    Spring 3.0 注解注入详解 2011-04-15 09:44 17ZOUGUO ITEYE博客 我要评论(1) 字号:T | T AD: 一.各种注解方式 1.@Autowired注解(不推荐 ...

  7. Servlet和HTTP请求协议-学习笔记01【Servlet_快速入门-生命周期方法、Servlet_3.0注解配置、IDEA与tomcat相关配置】

    Java后端 学习路线 笔记汇总表[黑马程序员] Servlet和HTTP请求协议-学习笔记01[Servlet_快速入门-生命周期方法.Servlet_3.0注解配置.IDEA与tomcat相关配置 ...

  8. 关于Android studio3.0的坑之butterknife 7.0.1(低版本)

    关于Android studio3.0的坑之butterknife 7.0.1(低版本) 我们在AS3.0里面是无法直接使用butterknife 内库插件的,会报错,如下图: 接下来看看怎么设置呢? ...

  9. Elasticsearch-mapper 基于注解方式生成mapping(2.0以上)

    Elasticsearch生成mapping的方式上有多种方式,我们可以把mapping做成配置文件,也可以用spring-data-elasticsearch基于注解生成. 在基于注解生成这种方式上 ...

最新文章

  1. Idea 七步建立Spring Mvc 的web项目,极其简单
  2. 给计算机系统的资产分配的记号被称为什么,哈工大2015计算机复试试题(25页)-原创力文档...
  3. 【最详细解析+难点分析】1085 PAT单位排行 (25分)
  4. 基于javascript的asp数据库操作类,含分页、字符串截取、用户登陆验证[原创]
  5. Linux操作系统需要做的准备
  6. php 可变变量 $$name
  7. 【Golang】go程序性能测试教程+总结
  8. 新款大屏卡罗拉linux系统,丰田卡罗拉大屏车载导航影音系统
  9. 三维数据可视化软件html5,基于 HTML5 的 WebGL 自定义 3D 摄像头监控模型 | 3D组态|图扑软件|数据可视化|blog...
  10. 数据基础设施,证券行业跑赢时代的新引擎
  11. 2019年安徽省模块七满分多少_2019年安徽中考总分是多少 考试科目及分值
  12. curl命令发送Post请求
  13. 十大跑步运动耳机品牌有哪些,质量比较好的运动耳机品牌推荐
  14. RPG 游戏数值系统—1
  15. 【C语言】解决 “error: function definition is not allowed here”
  16. 模拟CMOS集成电路设计入门学习(8)
  17. python脚本模式_python脚本怎么执行
  18. linux系统版搜狗输入法下载官网,搜狗输入法Linux版
  19. 产品经理常见面试题目——思维/场景问题
  20. 24--Excel图表与数据看板

热门文章

  1. 什么是栈,栈存储结构详情
  2. Linux如何在任务栏显示时间,在MFC[转载]在MFC状态栏显示时间 状态栏显示时间
  3. java aes key iv_java – AES / CBC真的需要IV参数吗?
  4. substring、substr以及slice、splice用法和区别
  5. mongodb一致性协议_mongodb副本集用一致性快照方法添加从节点步骤
  6. 服务器操作系统策略,Windows操作系统组策略应用全攻略(2)服务器教程 -电脑资料...
  7. 深度学习(DL)与卷积神经网络(CNN)学习笔记随笔-03-基于Python的LeNet之LR
  8. 深入理解JVM之JIT编译器(二)
  9. Java快速扫盲指南
  10. 什么是Code Review 代码审查