当前位置:网站首页>Several ways to bind controls --butterknife/viewbinding/databinding
Several ways to bind controls --butterknife/viewbinding/databinding
2022-07-28 12:11:00 【Fierce Bugs Bunny】
Several ways to bind controls
1. findViewById( routine )
Everyone is familiar with , I won't go into that
2.ButterKnife ( Butter knife , The library is deprecated , Only know )

A fast binding Android Annotation framework for fields and methods in the view , It's also Android In development once A commonly used quick annotation framework , adopt ButterKnife Reasonable use of , We can avoid writing repeatedly findViewById, Bind quickly in various situations view Various events in , Greatly improve the efficiency of development , It's in Java Compile time annotation processor , Automatically generated at compile time findViewById Code for , Although now it has been abandoned , But since it used to be so popular , We can also compare its advantages and disadvantages with other methods .

Simple view binding example :
1. Installing a plug-in
File -> Settings -> Plugins -> Search for ButterKnife , find Android ButterKnife Zelezny Then click Install, Restart again AS
2. Add dependency
implementation 'com.jakewharton:butterknife:10.1.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0'
// If it is kotlin, hold annotationProcessor Replace with kapt that will do
3. XML Code
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<TextView android:id="@+id/tv_HW" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />
<TextView android:id="@+id/tv_example" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="TextView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tv_HW" />
<Button android:id="@+id/btn_click_me" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Click Me" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tv_example" />
<Button android:id="@+id/btn_click_me_too" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="Click Me TOO" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/btn_click_me" />
<EditText android:id="@+id/edit_query" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@+id/btn_click_me_too" />
</androidx.constraintlayout.widget.ConstraintLayout>
4. Java Code
import androidx.appcompat.app.AppCompatActivity;
// Import necessary Libraries ( Use ButterKnife It doesn't seem to help you automatically import , If an error , Check whether the corresponding library is imported )
import android.os.Bundle;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Button;
import android.widget.Toast;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import com.example.mvcdemo.R;
public class MainActivity extends AppCompatActivity {
// Control annotation , And you cannot add private or static
@BindView(R.id.tv_HW)
TextView tvHelloWorld;
@BindView(R.id.tv_example)
TextView tvExample;
@BindView(R.id.edit_query)
EditText editText;
@BindView(R.id.btn_click_me)
Button btnClickMe;
@BindView(R.id.btn_click_me_too)
Button btnClickMeToo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// setContentView() Add later ButterKnife.bind(this);
ButterKnife.bind(this);
// You can use controls directly , Unwanted findViewById()
tvExample.setText(" The modified TextView");
editText.setText("123");
}
// Click the event to directly use the annotation @OnClick(R.id.XXXX), There is no need to use anonymous inner classes
@OnClick(R.id.tv_HW)
public void changeText(TextView tvHw){
tvHw.setText("Hello Android (change the World)");
}
// Handle two buttons together , Call the same event after two buttons are clicked
@OnClick({
R.id.btn_click_me, R.id.btn_click_me_too})
public void mulitButtonClick(){
// Function name customization
Toast.makeText(this, "U click Me", Toast.LENGTH_SHORT).show();
}
}
Here we only use our most conventional example to demonstrate , Other bindings are specifically visible :https://blog.csdn.net/qq_29924041/article/details/80538360
ButterKnife Official website :https://jakewharton-github-io.translate.goog/butterknife/?_x_tr_sl=en&_x_tr_tl=zh-CN&_x_tr_hl=zh-CN&_x_tr_pto=op,sc
Principle analysis :https://blog.csdn.net/hai_qing_xu_kong/article/details/78831979
3. Custom annotation binding ( understand )
https://blog.csdn.net/yangzhaomuma/article/details/51183110
4. **ViewBinding( Recommended , Focus on mastering )
ViewBinding yes Google stay 2019 year I/O A paragraph published at the conference Android View binding tool , It's also Google We strongly recommend that we use .
principle :Google stay Android gradle New features have been added to the plug-in , When a module Turn on ViewBind After function , When compiling, scan the layout file , Generate corresponding binding class ,findViewById The operation is completed in this automatically generated class .
Configuration preparation
Make sure your Android Studio yes 3.6 Or later , In the corresponding Project engineering module app In the catalog build.gradle Add the following configuration :
android {
……
// The configuration added is the following three lines
buildFeatures{
viewBinding = true
}
}
Click on the Sync Now, The system will automatically generate viewBinding class , for example MainActivity Will be generated with the name ActivityMainBinding Class ,LaunchActivity Will be generated with the name ActivityLaunchBinding Class , And so on ;
above viewBinding Class will be generated in the following path file ( If you want to understand the principle , You can view the code of these files )

After viewing the file , We can see that ,ViewBinding The final use is still findViewById, and ButterKnife different approaches but equally satisfactory results , The difference is ButterKnife Generated by compile time annotations ViewBinding class , and ViewBinding Through compile time scanning layout File generation ViewBinding class .
Use steps
Define global viewBinding Class object
to binding assignment , The corresponding value is viewBinding View of class object mapping , Bind variables to views
public class MainActivity2 extends AppCompatActivity {
private ActivityMain2Binding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMain2Binding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
}
}
- Control reference
binding.buttonExample.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity2.this, " Use ViewBinding Bound button ", Toast.LENGTH_SHORT).show();
}
});
5. DataBinding( Learn in advance )
DataBinding and LiveData and ViewModel All are JetPack Inside the frame , Learning these will also help us learn the following MVVM framework .
DataBinding Its characteristic is that it can Bind data directly to the interface .
So let's see DataBinding Specific use of :
Add the configuration
android {
compileSdkVersion 31
buildToolsVersion '30.0.3'
defaultConfig {
……
// Add the following code at this location
dataBinding {
enabled = true
}
}
}
Specific use
First step
Select the root layout in the layout , Press down Alt + Enter, The following options appear , Click on Convert to data binding layout

Then the layout is modified as follows :
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity3">
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
The second step
Fill the layout with data and controls
One way binding 、 Method binding
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<!-- Use variable Declare variables , hinder xml In the code, we can use @{
} call Java Variables and functions in code -->
<variable
name="user"
type="com.example.bingwaydemo.bean.User" />
<variable
name="click"
type="com.example.bingwaydemo.MainActivity3.Listener" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity3">
<EditText
android:id="@+id/et_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@{user.userName}"
android:hint=" Please enter a user name "
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@{user.password}"
android:hint=" Please input a password "
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_username" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Login"
android:onClick="@{()->click.changeUSerName()}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_password" />
<TextView
android:id="@+id/tv_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@{user.userName}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />
<TextView
android:id="@+id/tv_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@{user.password}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_username" />
<ImageView
android:id="@+id/image_head"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:src="@{user.headImage}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_password"
tools:srcCompat="@tools:sample/avatars" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Activity And the entity class
there User Class is used. LiveData, Give Way user When the object data changes ,Editext The data in will be automatically updated
import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;
import androidx.databinding.library.baseAdapters.BR;
/** * @ProjectName : bingWayDemo * @Author : Victor Scott * @Time : 2022/7/4 17:29 * @Description : describe */
// 1. Inherited from BaseObservable
public class User extends BaseObservable {
// 2. Use @Bindable Annotation Properties , Pay attention here , If the attribute is public Of , It needs to be annotated when declaring
// If the attribute is private Of , Need to be in get Method on comment
@Bindable
public String userName;
private String password;
private String headImage;
public String getHeadImage() {
return headImage;
}
public void setHeadImage(String headImage) {
this.headImage = headImage;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
// 3. stay public Just annotate the attribute , But in private Only annotations on attributes are useless , You also need to change the attribute value
// Inform out , there BR It's system generated
notifyPropertyChanged(BR.userName);
// With the above notifyPropertyChanged Similar usage , The difference is that The above method only informs the relevant controls to refresh the content ,
// The following method is to notify all controls to refresh the content
// notifyChange();
}
@Bindable
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", password='" + password + '\'' +
", headImage=" + headImage +
'}';
}
}
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import android.os.Bundle;
import android.util.Log;
import com.example.bingwaydemo.bean.User;
import com.example.bingwaydemo.databinding.ActivityMain3Binding;
public class MainActivity3 extends AppCompatActivity {
ActivityMain3Binding binding;
User user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main3);
/** adopt DataBindingUtil.setContentView Put the layout file and activity relation , Replaced the original setContentView() Method * It's not necessary findViewById, It only needs binding.button/binding.etUsername/bindind.etPassword Get the control directly * binding.getRoot() Used to get the top-level layout , stay Fragment This method is required in , return view */
user = new User();
user.setUserName("username");
user.setPassword("password");
user.setHeadImage("https://img2.baidu.com/it/u=2860188096,638334621&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500");
binding.setUser(user);
binding.setClick(new Listener());
}
public class Listener{
public void changeUSerName(){
user.setUserName(" Changed user name ");
Log.e("TAG", user.toString() );
}
}
}
We will find several benefits :
- No more writing findViewById() Such template code
- Created user The data in the object is automatically filled to the corresponding position , No more setText(), To modify, just change the variables in the class
The single-phase binding here refers to the time when the data entity changes , The layout file will be notified in time , Change the displayed content .
But now you find , modify EditView yes , Corresponding user Object userName There is no corresponding change , How can we make them realize bidirectional binding ?
It only needs take **@{}** Change to **@={}**, Add... In the middle = that will do
At this time, we will run demo, towards EditText When inputting content in, you will find , Below TextView The content in is also changing , Click on LOGIN Button ,user It can also be seen from the log ,user The object has indeed changed . thus , Bidirectional binding is basically realized .
边栏推荐
- 移动端人脸风格化技术的应用
- Matlab sets the size of graphics window and image and the position of legend
- Lua 中 __index、__newindex、rawget、rawset的理解
- Lua对table进行深拷贝
- How is the JS code compiled and executed by the browser engine?
- 从0开发一个自己的npm包
- Idea replication module
- Untiy中控制Animation的播放速度
- Develop your own NPM package from 0
- Final modifier attribute
猜你喜欢

Shell (II)

Hcip (configuration of GRE and mGRE and OSPF related knowledge)

Simple selection sort and heap sort
![[leetcode] 7. valid anagram · effective letter ectopic words](/img/bc/9806df1358c6f09db03ef2e771aa5a.png)
[leetcode] 7. valid anagram · effective letter ectopic words

Ruiji takeout - day01

Test platform (V) knowledge points supplement

Alexnet - paper analysis and reproduction

15. User web layer services (III)

Service workers let the website dynamically load webp pictures

LyScript 获取上一条与下一条指令
随机推荐
[real question of written examination]
移动端人脸风格化技术的应用
Unitywebrequest is used in unity to load network and local pictures
[pyGame practice] the super interesting bubble game is coming - may you be childlike and always happy and simple~
consul安装与配置
Direct insert sort and Hill sort
从零开始Blazor Server(2)--整合数据库
REST风格
How async await implements concurrency
[general database integrated development environment] Shanghai daoning provides you with Aqua Data Studio downloads, tutorials, and trials
[diary of supplementary questions] [2022 Niuke summer multi school 2] i-let fat tension
瑞吉外卖——Day01
Unity encountered a pitfall and the AB package failed to unload
Learn to use MySQL explain to execute the plan, and SQL performance tuning is no longer difficult
[pyGame practice] when the end of the world comes, how long can you live in a cruel survival game that really starts from scratch?
Training mode and practice of digital applied talents in Colleges and Universities under the integration of industry and education
boost官网搜索引擎项目详解
配置Jupyter远程服务器
[geek challenge 2019] babysql-1 | SQL injection
Code simplification