文章目录
1.简介
ButterKnife是一个专注于Android系统的View注入框架,以前总是要写很多findViewById
来找到View对象,有了ButterKnife可以很轻松的省去这些步骤。使用ButterKnife对性能基本没有损失,因为ButterKnife用到的注解并不是在运行时反射的,而是在编译的时候生成新的class。
ButterKnife利用了IOC的(Inverse of Controll)控制反转结构,2004年后改名为DI(dependency injection)依赖注入。目的是为了使类与类之间解耦合,提高系统的可扩展性和可维护性。越来越趋向于后端开发了。没错,这里的IOC和DI,跟Java框架中Spring里提到的一模一样
可能有读者不太理解这些说明的意思,我们可以举两个例子:
-
写Android项目的时候,总是不可避免地要写各种各样的界面。对于每一个写在XML文件上的控件,我们想要与这个控件进行互动,都要在java文件上获取与之对应的实例,比如这样:
TextView textview=(TextView)findViewById(R.id.textview); Button button=(Button)findViewById(R.id.button); ......
-
当我们获取到控件的实例后,可能会想给这个控件注册一些点击事件,比如这样:
button.setOnClickListen(){...}; ......
这样的代码,在我们编写业务的时候出现了太多,并且这是一个很繁琐的事情,为了简化(偷懒),使其自动生成相应的代码,ButterKnife应运而生。
当然,编写ButterKnife的相关代码本身还是耗费时间的。所以这篇博客额外会介绍一个与ButterKnife有关的插件:Zelezny。通过这个插件,可以自动生成ButterKnife的代码,达到快速完成这些重复工作的目的。
2.特性
老样子,想要查看某个框架的具体特性,我们直奔ButterKnife的GitHub官网:ButterKnife,其中介绍ButterKnife几个特性的原文如下:
- Eliminate findViewById calls by using @BindView on fields.
- Group multiple views in a list or array. Operate on all of them at once with actions, setters, or properties.
- Eliminate anonymous inner-classes for listeners by annotating methods with @OnClick and others.
- Eliminate resource lookups by using resource annotations on fields.
看到几个出现地这么频繁的单词:Eliminate
,就可以联想到该框架“消灭了”相当多的繁琐代码,去繁化简,正是ButterKnife最强的职能。
话不多活,让我们马上开始演示环节。由于该框架上手确实相对其他框架来说简单了不少,只需花上五分钟不到的时间就能掌握其全部的功能。
3.演示
3.1 集成
使用某个框架之前,集成都是必不可少的步骤。根据ButterKnife的GitHub官网,我们添加最新的依赖。除此之外,根据说明,要正常使用ButterKnife还需要设定compileOptions
闭包,指定JDK版本为1.8,代码如下:
android {
...
// Butterknife requires Java 8.
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'com.jakewharton:butterknife:10.2.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1'
}
3.2 布局文件和资源文件
为了更好地演示ButterKnife的全部功能,这里编写一个包含两个按钮和一个文本控件的布局,修改activity_main.xml,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<Button
android:id="@+id/btn_test_one"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="点击让文本变成数字!"/>
<Button
android:id="@+id/btn_test_two"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="点击让文本变成字母!"/>
<TextView
android:id="@+id/tv_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="100sp"
android:text="测试用的文本"/>
</LinearLayout>
除此之外,修改values/strings.xml,添加字符串资源信息,代码如下:
<resources>
<string name="app_name">Util-butterknife</string>
<string name="test_number">123456789</string>
<string name="test_latter">abcdefgh</string>
</resources>
我们想要实现的功能是:点击按钮1,将文本转换成数字;而点击按钮2,则将文本转换成字母,是一个比较简单的业务逻辑。
接下来,将介绍ButterKnife的三个主要功能:
- View注入
- 资源绑定
- 点击事件绑定
3.3 ButterKnife的主要功能
3.3.0 使用准备
在使用ButterKnife之前,注意在MainActivity的onCreate()
中使用ButterKnife.bind()
让ButterKnife绑定布局文件,代码如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 绑定ButterKnife
ButterKnife.bind(this);
}
3.3.1 View注入
View注入是ButterKnife的比较核心的功能,即我们在获取控件实例的时候,之前都是使用findViewById
,而现在只需要在字段上添加一个注解即可。现在给我们在布局文件中的三个控件注册实例,代码如下:
@BindView(R.id.btn_test_one)
Button btn_test_one;
@BindView(R.id.btn_test_two)
Button btn_test_two;
@BindView(R.id.tv_test)
TextView tv_test;
注意:使用ButterKnife声明的字段不能用private
修饰,因为ButterKnife的底层涉及到反射机制,如果使用了该修饰符就会报如图所示的错误:
3.3.2 资源绑定
资源绑定的功能类似于View注入,即将资源文件的值绑定到字段上,同样在字段上添加注解即可,代码如下:
@BindString(R.string.test_number)
String test_number;
@BindString(R.string.test_latter)
String test_latter;
这里两个字段的值虽然还没有取,但是已经由之前写的res/values.xml文件中同名的内容所提供了。
3.3.3 点击事件绑定
点击事件绑定的功能也很便捷,像之前我们给控件注册点击事件时都需要写一个监听器的实现类,然后实现其内部的onClick()
方法,而使用ButterKnife则让这一步骤变得更为简单,代码如下:
@OnClick({R.id.btn_test_one, R.id.btn_test_two})
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_test_one:
tv_test.setText(test_number);
break;
case R.id.btn_test_two:
tv_test.setText(test_latter);
break;
default:
break;
}
}
@OnClick
注解中的参数也可以只写单个控件,也可以写多个,这个需要考虑个人的需求。
3.4 Zelezny
之前有讲到使用Zelezny插件可以自动生成ButterKnife的相关代码,这里我们来尝试使用一下。
首先,如果你用的IDE是Android Studio,可以在Plugins菜单下搜索这个插件,如图中第一个所示:
将它安装下来,然后重启一下Android Studio,确认该插件已经集成到了你的IDE里,如图所示:
安装好后,将鼠标指针指向java代码中setContentView(R.layout.activity_main);
这行话上,右键选择 Generate,如图所示:
在弹开的选单中选择最后一项,如图所示:
选择选项之后,会弹出一个菜单,陈列出与该Activity绑定的布局中有什么控件,如图所示:
这里简单陈述一下菜单中各项属性的意思:
- 第一列复选框:勾上代表控件需要生成注解;
- 第二列复选框:勾上代表需要生成点击事件;
- Create ViewHolder:创建一个ViewHolder内部类,将ButterKnife相关代码封装进去;
- Split OnClick methods:将点击事件分离;
- Variable Name:该控件对应的变量名,默认名是XML布局文件里控件的id。
选择完成后,点击“confirm”按钮,就会自动生成ButterKnife相关代码。