dataBinding(重量级 商用):使用该组件可以实现mvvm架构,M : 数据仓库,V:界面(Activity xml),通过databinding使V 和M 连接起来,实现v-> M 与M-> 两个方向的控制。使用该组件时,不需要通findViewById方法获取布局中控件id,而是利用databinding ,当检测到数据(M)有变化时,V(xml)同步变化;反之既然。该组件使用的是APT注释器技术。
一、java使用dataBinding
步骤一:在app的build.gradle中启动dataBinding
//我使用的方法
android {
...
buildFeatures {
dataBinding true
}
}
//其他人使用的方法
// 打开DataBinding开关,访问闭包
// 第一种方式
dataBinding {
enabled true
}
// 第二种方式,直接去拿属性
dataBinding.enabled=true
步骤二:将布局转换为dataBinding布局(mv vm 架构中v)
点击布局上方小黄灯,即可转换为data布局,此时布局文件转变为 dataBinding 布局 + 正常布局两部分
步骤三:新建数据类(mv vm架构中m)
package com.test.databindingtestjava.model;
import androidx.databinding.BaseObservable;
import androidx.databinding.Bindable;
import androidx.databinding.Observable;
import com.test.databindingtestjava.BR;
/**
* @ClassName Student
* @Description TODO
* @Author lili
* @DATE 2022/11/2 13:54
*/
//数据类集成BaseObservable,这个数据类就拥有dataBinding能力了
public class Student extends BaseObservable {
private String name;
private int age;
//对应的get方法中添加@Bindable注释,会生成字段对应的数值标记
@Bindable
public int getAge() {
return age;
}
@Bindable
public String getName() {
return name;
}
//1、set方法中添加notifyPropertyChanged(BR.属性)
//2、这里BR文件是通过APT注释处理器 根据注释自动生成的BR文件,并且在布局文件中一定要将xml布局转换为dataBinding布局
//3、如果 BR文件找不到,则说明xml布局文件有问题。
public void setAge(int age) {
this.age = age;
notifyPropertyChanged(BR.age);
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
}
步骤四:在xml文件data标签中绑定数据类(m),实现dataBinding的双向绑定
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="student"
type="com.test.databindingtestjava.model.Student"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--@ 表示v->m,m只能驱动v,单向驱动-->
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{student.name}"
android:textSize="20pt"
android:textColor="@color/black"/>
<!-- 这里age是int类型,系统认为该int为资源文件,不能直接显示,需要将int类型转换为String类型-->
<TextView
android:id="@+id/tv_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@{String.valueOf(student.age)}"
android:textSize="20pt"
android:textColor="@color/black"/>
<!--"@= 表示 v->m,m->v双向驱动-->
<EditText
android:id="@+id/et_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@={student.name}"
android:textSize="20pt"
android:textColor="@color/black"/>
</LinearLayout>
</layout>
步骤五:activity/fragment中加载布局
package com.test.databindingtestjava;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import com.test.databindingtestjava.databinding.ActivityMaintestBinding;
import com.test.databindingtestjava.model.Student;
/**
* @ClassName MainActivityTest
* @Description TODO
* @Author lili
* @DATE 2022/11/2 13:46
*/
public class MainActivityTest extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//不需要使用setContentView()函数加载布局,使用下面的方法
ActivityMaintestBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_maintest);
//修改model数据,通过binding 同步修改view数据(textview 和 editText)
Student student = new Student();
student.setName("lilyy");
student.setAge(20);
binding.setStudent(student);
//布局中有editText控件,该控件实现view model 的双向控制,当手动编辑editText
//时,由于view 驱动model,model数据同时改变;又因为model 驱动view 同时TextView(name)
//同时改变
}
}
效果:
程序运行后效果:
编译EditText效果:
二、kontlin使用dataBinding
// Student.kt
package com.test.databingdingtestkotlin.model
import androidx.databinding.ObservableField
class Student {
//懒加载
val name:ObservableField<String> by lazy { ObservableField<String>() }
val age : ObservableField<Int> by lazy { ObservableField<Int>() }
}
//MainActivity.kt
package com.test.databingdingtestkotlin
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.test.databingdingtestkotlin.databinding.ActivityMainBinding
import com.test.databingdingtestkotlin.model.Student
class MainActivity : AppCompatActivity() {
private val student = Student()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//不需要使用setContentView()函数加载布局,使用下面的方法
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this,R.layout.activity_main)
//修改model数据,通过binding 同步修改view数据(textview 和 editText)
student.name.set("祝英台")
student.age.set(1)
binding.student = student
//布局中有editText控件,该控件实现view model 的双向控制,当手动编辑editText
//时,由于view 驱动model,model数据同时改变;又因为model 驱动view 同时TextView(name)
//同时改变
}
}