当前位置:网站首页>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 .
边栏推荐
- 【补题日记】[2022牛客暑期多校2]I-let fat tension
- A natural choice
- Learn to use MySQL explain to execute the plan, and SQL performance tuning is no longer difficult
- Ruiji takeout - day01
- [diary of supplementary questions] [2022 Niuke summer school 2] h-take the elevator
- [real question of written examination]
- Style conversion model style_ Transformer project instance pytorch implementation
- How to make the characters in the photos laugh? HMS core video editing service one click smile function makes people smile more naturally
- P5472 [noi2019] douzhudi (expectation, Mathematics)
- Detailed explanation of boost official website search engine project
猜你喜欢

Detailed explanation of boost official website search engine project

Upgrading of computing power under the coordination of software and hardware, redefining productivity

Will PFP be the future of digital collections?

可视化大型时间序列的技巧。

Test platform (V) knowledge points supplement

Introduction to the usage of SAP ui5 image display control avatar trial version

"Weilai Cup" 2022 Niuke summer multi school training camp 2

A hundred flowers bloom in data analysis engines. Why invest heavily in Clickhouse?

Develop your own NPM package from 0

Service Workers让网站动态加载Webp图片
随机推荐
【补题日记】[2022牛客暑期多校2]I-let fat tension
[geek challenge 2019] babysql-1 | SQL injection
ES6 knowledge points supplement
DNS series (III): how to avoid DNS spoofing
【补题日记】[2022杭电暑期多校2]K-DOS Card
Launcher sample code
Develop your own NPM package from 0
Redis installation
[real question of written examination]
Docker runs MySQL service
Upgrading of computing power under the coordination of software and hardware, redefining productivity
The reflect mechanism obtains the attribute and method information of class
多线程与高并发(三)—— 源码解析 AQS 原理
Go deadlock - when the channel meets mutex
Alexnet - paper analysis and reproduction
15. User web layer services (III)
安徽京准:北斗卫星同步时钟|北斗同步时钟|NTP网络时钟服务器
Lua makes a deep copy of table
108. Introduction to the usage of SAP ui5 image display control Avatar
Will PFP be the future of digital collections?