在Android中使用注解绑定控件和事件

在Android开发中,在代码中获取Activity中定义的控件和为控件绑定响应事件是件繁琐而无趣的事情,特别是在企业应用中,通常在一个界面(Activity)中会有大量的收入项,需要反复调用findViewById和setOnClickListener这样的函数。

下面的代码是一个简单的登录界面,包含用户名、密码两个输入框输入框和一个登录按钮。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class MainActivity extends AppCompatActivity {

private static final String TAG = "[" + MainActivity.class.getSimpleName() +"]";

private EditText txtUserId;

private EditText txtPwd;

private Button btnLogin;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

txtUserId = (EditText)findViewById(R.id.txtUserId);

txtPwd = (EditText)findViewById(R.id.txtPwd);

btnLogin = (Button)findViewById(R.id.btnLogin);

btnLogin.setOnClickListener(v -> {
Log.d(TAG, "Login clicked. userId = " + txtUserId.getText().toString());
});

}
}

使用butterknife库

要在 Android 项目中使用 butterknife 库,需要对项目完成两步设置:

  1. 在 build.gradle(Module:app) 文件中增加依赖项:
1
2
3
4
5
dependencies {
// ... 原有的依赖项
implementation 'com.jakewharton:butterknife:10.1.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
}

并将Java的版本设置为1.8

1
2
3
4
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

修改后完整的 build.gradle(Module:app) 文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
apply plugin: 'com.android.application'

android {
compileSdkVersion 29
buildToolsVersion "29.0.1"
defaultConfig {
applicationId "cn.com.hohistar.tutorial.basicwidgettutorial"
minSdkVersion 15
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.jakewharton:butterknife:10.1.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
}
  1. 在 build.gradle(Project: xxxx) 文件中增加: (替换 xxxx 为你的项目名)
1
classpath 'com.jakewharton:butterknife-gradle-plugin:10.0.0'

修改后完整的 build.gradle(Project: xxxx) 文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
repositories {
google()
jcenter()

}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.2'
classpath 'com.jakewharton:butterknife-gradle-plugin:10.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
jcenter()

}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

初始化 butterknife

在每个想要使用 butterknife 功能的 Activity ,都必须要进行一次初始化。通常这个工作是放在 Activity 的 onCreate 方法中来完成, 代码如下:

1
2
3
4
5
6
7
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

ButterKnife.bind(this);
}

代码中第6行就是调用 ButterKnife 的 bind 静态函数进行初始。注意: 对于每个 Activity 都一定要执行这行代码进行初始化,否则会出现注解(绑定)既不生效,也不报错的情况。

绑定按钮单击事件

在前面的例子中,为了绑定按钮的单价事件,我们需要首先获取按钮的实例(findViewById),然后调用setOnClickLister方法进行绑定。使用 ButterKnife 后,我们只需要使用 @OnClick 注解就可以完成绑定。下面对比一下代码:

旧的代码

1
2
3
4
5
btnLogin = (Button)findViewById(R.id.btnLogin);

btnLogin.setOnClickListener(v -> {
Log.d(TAG, "Login clicked. userId = " + txtUserId.getText().toString());
});

新的代码

1
2
3
@OnClick(R.id.btnLogin) void onLogin() {
Log.d(TAG, "Login clicked. userId = " + txtUserId.getText().toString());
}

可以看到,新的代码中,直接通过 @OnClick 注解的参数指明需要绑定的对象,简介很多。

修改后完整的 Activity 代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class MainActivity extends AppCompatActivity {

private static final String TAG = "[" + MainActivity.class.getSimpleName() +"]";

private EditText txtUserId;

private EditText txtPwd;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

txtUserId = (EditText)findViewById(R.id.txtUserId);

txtPwd = (EditText)findViewById(R.id.txtPwd);
}

@OnClick(R.id.btnLogin) void onLogin() {
Log.d(TAG, "Login clicked. userId = " + txtUserId.getText().toString());
}

}

绑定屏幕上的控件

在原来的程序中,当在程序中需要获取输入框的值时,我们需要首先用 findViewById 取得控件的实例,在进行操作:

1
2
3
4
5
6
7
8
9
10
// 定义
private EditText txtUserId;
private EditText txtPwd;

// 获取实例
txtUserId = (EditText)findViewById(R.id.txtUserId);
txtPwd = (EditText)findViewById(R.id.txtPwd);

// 获取数据
Log.d(TAG, "Login clicked. userId = " + txtUserId.getText().toString());

使用 ButterKnife, 用 @BindView 直接进行绑定,这样代码就会更简洁些:

1
2
3
4
5
6
// 定义
@BindView(R.id.txtUserId) EditText txtUserId;
@BindView(R.id.txtPwd) EditText txtPwd;

// 获取数据
Log.d(TAG, "Login clicked. userId = " + txtUserId.getText().toString());

可以看到,操作数据的代码没变,但省了获取实例的代码。

本文标题:在Android中使用注解绑定控件和事件

文章作者:梅老师

发布时间:2019年08月07日 - 19:08

最后更新:2020年09月16日 - 08:09

原始链接:https://www.mls-tech.info/app/android/android-bind-with-annotation/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。