Use jetpack's data binding library to teach you to simplify the amount of code
Data binding library
The data binding library is a support library with which you can use a declarative format (rather than programmatically) to bind the interface components in the layout to the data source in the application.
在以前写代码,我们都是通过findviewbyid来找到xml代码中的控件,
然后再操作,我们可以发现,当代码量的增多,罪魁祸首少不了他,
每次我们都要去找控件,有时候还容易忘记,导致空指针异常,
今天使用数据绑定库就可以避免此类问题,同时可以简化代码量
Steps for usage
Reference related dependencies
Add the following code to android in build.gradle
dataBinding{
enabled = true
}
Introduce dependencies such as viewmodel and livedata
def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
Change the xml code format
We use layout to wrap the previous code. At the same time, we need to name the control and move it to the 在 <data>
label in the layout tag, which can be variable
used to specify the data source.
The data source of the code below is MyViewModel
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">
<data>
<variable
name="data"
type="com.mt.databinding.MyViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:textSize="30dp"
android:gravity="center"
android:id="@+id/textView2"
android:layout_width="296dp"
android:layout_height="0dp"
android:layout_marginStart="41dp"
android:layout_marginLeft="41dp"
android:layout_marginTop="43dp"
android:layout_marginBottom="92dp"
android:text="@{String.valueOf(data.Number)}"
app:layout_constraintBottom_toTopOf="@+id/imageView2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:text="+1"
android:id="@+id/imageView"
android:layout_width="128dp"
android:layout_height="167dp"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="35dp"
android:layout_marginRight="35dp"
android:layout_marginBottom="264dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/imageView2"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@android:drawable/ic_input_add"
android:onClick="@{()->data.addNumber(1)}"
/>
<Button
android:onClick="@{()->data.addNumber(-1)}"
android:text="-1"
android:id="@+id/imageView2"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="56dp"
android:layout_marginRight="56dp"
android:layout_marginBottom="273dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView"
app:layout_constraintTop_toBottomOf="@+id/textView2"
app:srcCompat="@android:drawable/presence_busy" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
android:onClick="@{()->data.addNumber(-1)}"
android:text="@{String.valueOf(data.Number)}"
will talk about it later, now you look at the layout usage layout package
Define ViewModel
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class MyViewModel extends ViewModel {
MutableLiveData<Integer> Number;
public MutableLiveData<Integer> getNumber() {
if(Number == null){
Number = new MutableLiveData<>();
Number.setValue(0);
}
return Number;
}
//对数据的操作函数
public void addNumber(int n){
Number.setValue(Number.getValue()+n);
}
}
Get xml
setContentView(R.layout.activity_main);
In the previous code, we obtained xml through the above code.
Now we don’t have to do this at all. We pass the xml code that we just modified, and the system will automatically generate a class for us.该类是以xml文件的首字母大写+Bind所构成,例如ActivityMainBinding就是activity_main的类
Get layoutDataBindingUtil.setContentView
ActivityMainBinding binding= DataBindingUtil.setContentView(this,R.layout.activity_main);
Bind ViewModel
First get the myviewmodel, and then move the setdata in the ActivityMainBinding class to bind the data for the layout. At the same time, you need to set the setLifecycleOwner to monitor the data changes
myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
binding.setData(myViewModel);
binding.setLifecycleOwner(this);
Monitoring the button
Before we used setOnClickListener to operate,
now we can implement it in the xml layout
First we need to bind our data source
<data>
<variable
name="data"
type="com.mt.databinding.MyViewModel" />
</data>
Then, adding @{String.valueOf(data.Number)}
@{} to the text attribute in the layout code of our TextView is a fixed writing method, and some java code can be written
Then add android:onClick="@{()->data.addNumber(1)}"
@{} to the button button, which is a function, which is the function you defined in the viewmodel, and pass in 1 as a parameter.
Add another button of the same kindandroid:onClick="@{()->data.addNumber(-1)}"
Compare the amount of code before
Before the code:
public class MainActivity extends AppCompatActivity {
ImageView button1,button2;
TextView textView;
MyViewModel myViewModel;
ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init_view();
myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
binding.setData(myViewModel);
binding.setLifecycleOwner(this);
myViewModel.getNumber().observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
binding.textView2.setText(String.valueOf(integer));
}
});
binding.imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
myViewModel.addNumber(1);
}
});
binding.imageView2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
myViewModel.addNumber(-1);
}
});
}
private void init_view() {
textView=findViewById(R.id.textView2);
button1=findViewById(R.id.imageView);
button2=findViewById(R.id.imageView2);
}
}
Now after using jetpack's data binding
public class MainActivity extends AppCompatActivity {
MyViewModel myViewModel;
ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
binding.setData(myViewModel);
binding.setLifecycleOwner(this);
}
}
The change in the amount of code is obvious! ! ! !
Next, I will make a case for further explanation
Code address:
Use jetpack's data binding library to teach you to simplify the amount of code