上一篇文章提的那本书,源代码可以从这里下载,只需要简单注册一下即可.
然后按照书里第三章创建了一个非常简单的输入美元,然后按照0.85的汇率转换成欧元的应用.
所做的事情其实和Web
开发很类似,先有一个Activity
也就是页面,然后给这个页面添加一个输入框,一个显示文本的框,和一个按钮. 然后编写这个页面对应的Java
类,添加一个方法或者说事件处理器,在按钮按下的时候触发事件,从输入框中读取金额,然后进行计算,再渲染到文本框中.
获取资源的两种方式
根据ID
查找视图(页面组件)
在之前已经知道,所有的资源可以通过R
类来访问,看一下这个简单项目中的代码:
EditText dollarText = findViewById(R.id.dollarText);
TextView textView = findViewById(R.id.textView);
这个R.id.
后边的部分,就是视图的id
名称,通过这个方法,可以直接获取视图,然后就可以更改样式或者内容,类似于WEB
开发中获取HTML
元素.
在Android Studio 3.6
之前,想要获取元素,唯一的办法就是像上边的代码一样使用findViewById()
方法(有AppCompatActivity
类提供).
这个方法比较准确方便,如果是有不便之处的话,就是还不能引用尚未创建的元素,否则会报空指针错误.
视图绑定 View Bindings
在AS 3.6
之后,如果设置了启用视图绑定,AS
会自动为每一个layout
布局文件(layout
目录下的XML
文件)创建一个绑定类,这个绑定类根据布局文件的名称,改成驼峰之后加上Binding
来命名,比如activity_main.xml
的绑定类就是ActivityMainBinding
.这样通过类名就可以来访问视图资源,现在就来看一下如何将原来的代码改造成使用视图绑定.
改造原来的代码
启用视图绑定
默认情况下,视图绑定功能没有启用.如果要启用的话,必须对模块(Module)级别的build.gradle
文件进行修改.在左侧的1.Project
窗口最下边的Gradle Scripts
中, 找到build.gradle(Module:XXXX.app)
,双击打开,文件中的内容如下:
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 29
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.ebookfrenzy.androidsample"
minSdkVersion 26
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 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
在其中的android
部分中,增加如下配置:
android {
......
buildFeatures {
viewBinding = true
}
......
我这里配置好之后,重新同步,gradle
会去下载视图绑定所需要的文件.之后需要重新编译,在右侧Gradle
菜单中选择Tasks-build-build
即可.
改造代码
先来看一下原始的代码:
package com.ebookfrenzy.androidsample;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void convertCurrency(View view) {
EditText dollarText = findViewById(R.id.dollarText);
TextView textView = findViewById(R.id.textView);
if (!dollarText.getText().toString().equals("")) {
float dollarValue = Float.valueOf(dollarText.getText().toString());
Float euroValue = dollarValue * 0.85F;
textView.setText(euroValue.toString());
} else {
textView.setText(R.string.no_value_string);
}
}
}
接下来开始改造.
添加视图绑定类的引用
由于我们知道了绑定类的类名应该是ActivityMainBinding
,先给当前类添加一个域:
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
}
启用了视图绑定之后,AS
可以自动提示补完这个类,说明已经认出来了.
删除那些R
类的代码并替换成绑定类"进入"的代码
这些代码在onCreate
和我们自行编写的代码中都有,分别是:
setContentView(R.layout.activity_main);
EditText dollarText = findViewById(R.id.dollarText);
TextView textView = findViewById(R.id.textView);
然后一个一个来改,先是onCreate
方法:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
}
这里的视图原来是直接通过R
类引用,现在是从绑定类中获取View
对象并进行显示.同时这里也初始化了binding
对象.
然后是自己编写的业务方法:
public void convertCurrency(View view) {
if (!binding.dollarText.getText().toString().equals("")) {
float dollarValue = Float.valueOf(binding.dollarText.getText().toString());
Float euroValue = dollarValue * 0.85F;
binding.textView.setText(euroValue.toString());
} else {
binding.textView.setText(R.string.no_value_string);
}
}
这里就是把获取View
对象的方法,从原来的R
类改成了bing.id
的方式.
在开启视图绑定之后,原来的findViewById()
依然可用,而且可以同时使用.这本书里还提到,由于代码量的关系,在代码示例中,还是使用findViewById()
方法,但是在实际开发中,推荐大家使用AS
的视图绑定功能.