使用jetpack的数据绑定库教你简化代码量
数据绑定库
数据绑定库是一种支持库,借助该库,您可以使用声明性格式(而非程序化地)将布局中的界面组件绑定到应用中的数据源。
在以前写代码,我们都是通过findviewbyid来找到xml代码中的控件,
然后再操作,我们可以发现,当代码量的增多,罪魁祸首少不了他,
每次我们都要去找控件,有时候还容易忘记,导致空指针异常,
今天使用数据绑定库就可以避免此类问题,同时可以简化代码量
使用步骤
引用相关依赖
再build.gradle中的android添加下面代码
dataBinding{
enabled = true
}
引入viewmodel,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'
改变xml代码格式
我们运用layout来包裹之前的代码,同时需要命名控件移至layout标签当中在 <data>
标签中,可以指定variable
用于指定数据源
下面的代码的数据源是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)}"
在后面会讲到,现在你就看看布局使用layout包裹即可
定义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);
}
}
获取xml
setContentView(R.layout.activity_main);
再之前的代码当中我们获取xml是通过上述代码,
现在我们可以完全不用这么做了,我们通过刚刚修改的xml代码,系统就会自动帮我们生成一个类,该类是以xml文件的首字母大写+Bind所构成,例如ActivityMainBinding就是activity_main的类
获取布局DataBindingUtil.setContentView
ActivityMainBinding binding= DataBindingUtil.setContentView(this,R.layout.activity_main);
绑定ViewModel
首先获取myviewmodel,然后动过ActivityMainBinding 类里面的setdata,为布局绑定数据,同时需要设置setLifecycleOwner,来监听数据的改变
myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
binding.setData(myViewModel);
binding.setLifecycleOwner(this);
对按钮的监听
之前我们通过setOnClickListener来操作,
现在我们可以再xml布局当中来实现
首先我们需要绑定我们的数据源
<data>
<variable
name="data"
type="com.mt.databinding.MyViewModel" />
</data>
然后我们TextView的布局代码中text属性中加入@{String.valueOf(data.Number)}
@{}就是固定写法,里面可以写一些java代码
再button按钮中加入android:onClick="@{()->data.addNumber(1)}"
@{}里面是函数,就是你在viewmodel中定义的函数,并传入1作为参数
同类另一个按钮加入android:onClick="@{()->data.addNumber(-1)}"
对比之前代码量
之前代码:
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);
}
}
现在使用jetpack的数据绑定之后
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);
}
}
这代码量的变化很明显吧!!!!
再下面我会做一个案例进行进一步的说明