作用
- 让布局文件承担了部分原本属于页面的工作,使页面与布局耦合度进一步降低
应用
- 需要在build.gradle中开启DataBinding
defaultConfig {
minSdk 21
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
//开启
dataBinding{
enabled = true
}
}
- activity中设置
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
activityMainBinding.setIdol(new Idol("我"));
}
}
- 然后布局里面改为databinding布局
<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>
<variable
//变量名字
name="idol"
type="com.example.databinding.Idol" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@ id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="TextView"
//获取变量属性
android:text="@{idol.name}"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@ id/guideline2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@ id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
import
布局里还可以import类
代码语言:javascript复制 public class IdolUtils {
public static String getIdolName() {
return "name is name";
}
}
//布局文件中
<data>
<variable
name="idol"
type="com.example.databinding.Idol" />
<import type="com.example.databinding.IdolUtils"/>
</data>
//使用
android:text="@{IdolUtils.getIdolName()}"
事件绑定
- 定义事件处理类
public class EventHandleListener {
private Context context;
public EventHandleListener(Context context) {
this.context = context;
}
public void onClick(View view){
Toast.makeText(context, "哈哈哈",Toast.LENGTH_SHORT).show();
}
}
- 布局中绑定事件处理
<data>
<variable
name="idol"
type="com.example.databinding.Idol" />
<variable
name="eventHandle"
type="com.example.databinding.EventHandleListener" />
<import type="com.example.databinding.IdolUtils"/>
</data>
<Button
android:id="@ id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:onClick="@{eventHandle.onClick}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@ id/guideline2" />
- activity中设置
activityMainBinding.setEventHandle(new EventHandleListener(this));
二级页面的绑定
- 二级页面中也要是binding
- 然后用app命名空间传给二级页面
//主页面
<include layout="@layout/sub"
app:idol="@{idol}"/>
//子页面
<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>
<variable
name="idol"
type="com.example.databinding.Idol" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@ id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{idol.name}"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="TextView" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
用BaseObservable双向绑定
- 需要继承BaseObservable
public class UserViewModel extends BaseObservable {
private User user;
public UserViewModel() {
this.user = new User("name");
}
@Bindable
public String getUserName() {
return user.getName();
}
public void setUserName(String userName){
if (userName != null && userName.equals(user.name)){
user.name = userName;
notifyPropertyChanged(BR.userName);
}
}
}
- 布局里使用也有点变化
//导入数据这里没有变
<data>
<variable
name="userViewModel"
type="com.example.databinding2.UserViewModel" />
</data>
<EditText
android:id="@ id/editTextTextPersonName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
//主要是这里变化,多了一个=号
android:text="@={userViewModel.userName}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
- activity里设置
ActivityMainBinding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
viewDataBinding.setUserViewModel(new UserViewModel());
用ObservableField进行双向绑定,这个更加简洁
主要是ViewModel里要修改下
代码语言:javascript复制public class UserViewModel2 {
private ObservableField<User> observableField;
private User user;
public UserViewModel2() {
this.user = new User("name");
observableField = new ObservableField<>();
observableField.set(user);
}
public String getUserName() {
return observableField.get().name;
}
public void setUserName(String userName){
if (userName != null && userName.equals(user.name)){
observableField.get().setName(userName);
}
}
}
布局和activity里都一样
坑
ActivityMainBinding找不到
- 布局必须是binding layout
码字不易,求转发,求点在看,求关注,感谢!