Databinding使用篇(迅速上手)
使用前需要在模块级别的build.gradle里面的android闭包里添加:
 dataBinding{
      enabled = true
  }
接着在layout文件中按下Alt + 回车, 将布局转换成data binding layout即可,此时编译就会生成对应的Binding java类
 
layout文件命名为xxx_xxx.xml生成的java类命名格式为XxxXxxBinding.java
 
例如:activity_main.xml --> ActivityMainBinding.java
 
常见使用:
1. 赋值 (variable的种类有很多种,View,基本类型,引用类型等各种各样的)
 
在xml的 标签下添加标签,写入对应的数据名,以及数据类型
<data>
  <variable
      name="test"
      type="com.dongnaoedu.databinding.Idol" />
  <variable
      name="eventHandle"
      type="com.dongnaoedu.databinding.EventHandleListener" />
<!--      <variable-->
<!--           name="starUtil"-->
<!--            type="com.dongnaoedu.databinding.StarUtils" />-->
<!--        使用静态类的方法可以直接import然后使用 而不需要在activity里面setXXX-->
 <import type="com.dongnaoedu.databinding.StarUtils" />
</data>
variable标签携带的是数据,而import标签则可以引入静态方法
 
导入数据后就可以使用数据了,在xml中使用 "@{}"的格式去赋值,或者使用工具类`
例如:
<?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">
<androidx.constraintlayout.widget.ConstraintLayout
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">
  <ImageView
      android:id="@+id/imageView"
      android:layout_width="300dip"
      android:layout_height="300dip"
      android:src="@drawable/wangzhai"
      app:layout_constraintBottom_toTopOf="@+id/guideline"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintHorizontal_bias="0.495"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent"
      app:layout_constraintVertical_bias="0.803"
      tools:srcCompat="@tools:sample/avatars" />
  <TextView
      android:id="@+id/textView"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="@{test.name}"
      android:textSize="24sp"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintHorizontal_bias="0.498"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="@+id/guideline"
      app:layout_constraintVertical_bias="0.176"
      tools:text="姓名" />
  <TextView
      android:id="@+id/textView2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="48dp"
      android:text="@{eventHandle.getStar(test.star)}"
      android:textSize="18sp"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintHorizontal_bias="0.498"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toBottomOf="@+id/textView"
      tools:text="五星" />
  <androidx.constraintlayout.widget.Guideline
      android:id="@+id/guideline"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:orientation="horizontal"
      app:layout_constraintGuide_percent="0.5" />
  <Button
      android:id="@+id/button2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginBottom="60dp"
      android:text="喜欢"
      android:onClick="@{()->eventHandle.buttonOnClick()}"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintHorizontal_bias="0.498"
      app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<data>
  <variable
      name="test"
      type="com.dongnaoedu.databinding.Idol" />
  <variable
      name="eventHandle"
      type="com.dongnaoedu.databinding.EventHandleListener" />
<!--      <variable-->
<!--           name="starUtil"-->
<!--            type="com.dongnaoedu.databinding.StarUtils" />-->
<!--        使用静态类的方法可以直接import然后使用 而不需要在activity里面setXXX-->
 <import type="com.dongnaoedu.databinding.StarUtils" />
</data>
</layout>
注意,使用variable还需要在java代码中为binding对象传入数据:
 
public class MainActivity extends AppCompatActivity {
 @Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
     Idol idol = new Idol("旺仔",5);
     activityMainBinding.setTest(idol); //为binding设置数据
     activityMainBinding.setEventHandle(new EventHandleListener(this));//为binding设置数据
 }
}
2. 在xml设置点击回调方法
 
当回调方法中参数只有一个且为View时:
public class EventHandleListener {
 private Context context;
 public EventHandleListener(Context context) {
     this.context = context;
 }
 //回调方法,一个参数且为View
 public void buttonOnClick(View view){
     Toast.makeText(context,"喜欢 ",Toast.LENGTH_SHORT).show();
 }
}
使用:xxx类名.xxx方法名
 
android:onClick="@{eventHandle.buttonOnClick}"
回调方法为其他类型时:
public class EventHandleListener {
 private Context context;
 public EventHandleListener(Context context) {
     this.context = context;
 }
 //回调方法使用没有带View的参数时
 public void buttonOnClick(int data,String name){
     Toast.makeText(context,"喜欢  " + data + " "+name,Toast.LENGTH_SHORT).show();
 }
}
使用:()->xxx类名.xxx方法名(参数) 
 
xxxxxxxxxx android:onClick="@{()->eventHandle.buttonOnClick(1,test.name)}"
当然也可以写成:
android:onClick="@{(view)->eventHandle.buttonOnClick(1,test.name)}"
只不过此处的view可以忽略不写,但俩种方式都是一样的
 
因为onclick方法的参数是(View view),所以在回调方法需要传入View对象的时候,我们可以这样子
public class EventHandleListener {
 private Context context;
 public EventHandleListener(Context context) {
     this.context = context;
 }
 public void buttonOnClick(View view,int data,String name){
     Toast.makeText(context,"喜欢  " + data + " "+name,Toast.LENGTH_SHORT).show();
 }
}
使用:
android:onClick="@{(theview)->eventHandle.buttonOnClick(theview,1,test.name)}"
上述也是通过lambda表达式将onclick的参数view传入到我们的回调方法中
 
3. 属性值使用其他view的属性时
 
例如:
     <TextView
         android:id="@+id/textView2"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="48dp"
         android:text="@{StarUtils.getStar(test.star)}"
         android:textSize="18sp"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintHorizontal_bias="0.498"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@+id/textView"
         tools:text="五星" />
我要使用上面 id = textView2的text时
     <Button
         android:id="@+id/button2"
         android:text="@{textView2.text}"/>
    <!--    button2的text使用了上面id为textView2的text -->
4. 将variable值传入给include包含的子布局时:(前提是variable的type类型一致)
 
例如:子布局 sub
 <data>
     <variable
         name="sub"
         type="com.dongnaoedu.databinding2.Idol" />
 </data>
父布局:
 <data>
     <variable
         name="idol"
         type="com.dongnaoedu.databinding2.Idol" />
 </data>
在父布局中将 idol 传给 子布局的sub
     <include
         layout="@layout/sub"
         app:sub="@{idol}"/>
5. 设置BindingAdapter
 
例如:为imageview设置图片值
<?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>
     <variable
         name="networkImage"
         type="String" />
     <variable
         name="localImage"
         type="int" />
 </data>
 <androidx.constraintlayout.widget.ConstraintLayout
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     tools:context=".MainActivity">
     <ImageView
         android:id="@+id/imageView"
         app:image="@{networkImage}"
         app:defaultImageResource="@{localImage}"
         android:layout_width="300dip"
         android:layout_height="300dip"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         tools:srcCompat="@tools:sample/avatars" />
 </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
写个adapter的java类:
public class ImageViewBindingAdapter {
 /**
 1.如果重载方法有多个参数的,会优先调用多个参数的
 2.优先级:(1)Picasso.get().load(url).placeholder(R.drawable.ic_launcher_background).into(imageView);
   * (2)优先级是大于imageView.setImageResource(resId);
   * 即 使用(1)加载图片后,再使用(2)也无法改变图片内容
   */
    //加载网络图片
    @BindingAdapter("image")
    public static void setImage(ImageView imageView, String url){
        Log.d("ning", "setImage: "  + "我是网络图片");
        if(!TextUtils.isEmpty(url)){
            Picasso.get()
                    .load(url)
                    .placeholder(R.drawable.ic_launcher_background)
                    .into(imageView);
        }else{
            imageView.setBackgroundColor(Color.GRAY);
        }
    }
    //加载本地图片
    @BindingAdapter("defaultImageResource")
    public static void setImage(ImageView imageView, int resId){
        Log.d("ning", "setImage: "  + "我是本地图片");
        imageView.setImageResource(resId);
    }
//    //参数可选,网络图片为空时,加载本地图片
    @BindingAdapter(value = {"image", "defaultImageResource"}, requireAll = false)
    public static void setImage(ImageView imageView, String url, int resId){
        Log.d("ning", "setImage: "  + "我是本地+网络图片");
        if(!TextUtils.isEmpty(url)){
            Picasso.get()
                    .load(url)
                    .placeholder(R.drawable.ic_launcher_background)
                    .into(imageView);
        }else{
            imageView.setImageResource(resId);
        }
    }
}
记得给binding类传入值:
public class MainActivity extends AppCompatActivity {
    String TAG = "ning";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: ");
        ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        activityMainBinding.setLocalImage(R.drawable.wangzhai);
        activityMainBinding.setNetworkImage(networkUrl);
    }
}
6.双向绑定-- ObservableField
 
双向绑定在xml中要区别于赋值,赋值是"@{}", 而双向绑定是"@={}"
 
用法举例:
存放observableField数据的类:
public class UserViewModel{
    public ObservableField<User> userObservableField;
    public UserViewModel(){
        User user = new User("Jack");
        userObservableField = new ObservableField<>();
        userObservableField.set(user);
        Log.d("TAG", "InitchangeValue: " + userObservableField.get());
    }
}
user类:
public class User {
    private String userName;
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public User(String userName) {
        this.userName = userName;
    }
}
使用:
 xml中editText:
<?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>
        <variable
            name="userViewModel"
            type="com.dongnaoedu.databinding5.UserViewModel" />
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
        <EditText
            android:id="@+id/editText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ems="10"
            android:inputType="textPersonName"
            android:text="@={userViewModel.userObservableField.userName}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
        <Button
            android:id="@+id/button"
            android:onClick="changeValue"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="chageValue"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/editText" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
注意上面直接是 android:text="@={userViewModel.userObservableField.userName}", 因为默认是调用getUserName()了。
 
java代码中:
public class MainActivity extends AppCompatActivity {
    UserViewModel viewModel;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        viewModel = new UserViewModel();
        activityMainBinding.setUserViewModel(viewModel); //为binding设置值
        //开启一个定时任务在java代码中改变user的username
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                for(int i = 0; i < 3; i++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    User user = (User)viewModel.userObservableField.get();
                    user.setUserName(String.valueOf(i));
                    viewModel.userObservableField.notifyChange();  //一定要调用notifyChange()方法通知属性值改变了
                }
            }
        },2000);
    }
    /**
     * button的回调方法,用来测试值是否有双线绑定
     * @param view
     */
    public void changeValue(View view) {
        User user = (User)viewModel.userObservableField.get();
        Log.d("TAG", "changeValue: " + viewModel.userObservableField.get() + "       " + user.getUserName());
    }
}
运行后发现-- 在java代码中改变user的username都会反馈到UI上,在editText中随便输入,都会改变user的username值,做到了数据和UI间的双向绑定。
 
7 双向绑定BaseObservable的使用
 
1. 写个类继承BaseObservable,并给所要使用双向绑定的成员变量添加getter和setter方法
2. getter方法要加上@Bindable, 加上后才会生成对应的字段的BR字段
3. 在setter中调用notifyPropertyChanged(BR.xxx) 去通知对应数据改变了
4. 在xml中要用 "@={xxx.xxx}"的形式。
android:text="@={fileViewModel.cacheGenerateSize}"
使用
写类对象,并提供对应的getter和setter方法。 以及为getter方法打上@Bindable注解,setter方法调用notifyPropertyChanged()
 
public class FileViewModel extends BaseObservable {
    private String systemTotalSpace  = ""; //系统的总存储空间, MB
    @Bindable
    public String getSystemTotalSpace() {
        return systemTotalSpace;
    }
    public void setSystemTotalSpace(String systemTotalSpace) {
        if(systemTotalSpace != null && !systemTotalSpace.equals(this.systemTotalSpace)){
            this.systemTotalSpace = systemTotalSpace;
            notifyPropertyChanged(BR.systemTotalSpace);
        }
    }
在xml中:传入对应值
 
    <data>
       <variable
           name="fileViewModel"
           type="net.sunniwell.fileautobuilder.FileViewModel" />
    </data>
    
                     <TextView
                          android:id="@+id/tv_system_total_space"
                          android:layout_gravity="end"
                          android:layout_width="wrap_content"
                          android:layout_height="wrap_content"
                          android:gravity="center"
                          android:text="@={fileViewModel.systemTotalSpace}"
                          android:textColor="#60acfc"
                          android:textSize="20sp"
                          android:layout_marginBottom="5dp" />
在java代码中将fileViewModel对象传入给打他binding 
 
fileViewModel.setSystemTotalSpace(" " + Constraint.SYSTEM_TOTAL_SPACE + "MB");
mbind.setFileViewModel(fileViewModel);
java代码中要改变值时,直接调用fileviewmodel.setxxx()即可
 
8. databinding结合viewmodel以及livedata
 
结合livedata只需要加上:
activityMainBinding.setLifecycleOwner(this);
使用举例(简单记分牌)
viewmodel:
public class MyViewModel extends ViewModel {
    private MutableLiveData<Integer> aTeamScore;
    private MutableLiveData<Integer> bTeamScore;
    private Integer aLast;
    private Integer bLast;
    public MutableLiveData<Integer> getaTeamScore() {
        if(aTeamScore == null){
            aTeamScore = new MutableLiveData<>();
            aTeamScore.setValue(0);
        }
        return aTeamScore;
    }
    public MutableLiveData<Integer> getbTeamScore() {
        if(bTeamScore == null){
            bTeamScore = new MutableLiveData<>();
            bTeamScore.setValue(0);
        }
        return bTeamScore;
    }
    public void aTeamAdd(int i){
        saveLastScore();
        aTeamScore.setValue(aTeamScore.getValue() + i);
    }
    public void bTeamAdd(int i){
        saveLastScore();
        bTeamScore.setValue(bTeamScore.getValue() + i);
    }
    public void undo(){
        aTeamScore.setValue(aLast);
        bTeamScore.setValue(bLast);
    }
    public void reset(){
        aTeamScore.setValue(0);
        bTeamScore.setValue(0);
    }
    //记录上一次的分数
    private void saveLastScore(){
        this.aLast = aTeamScore.getValue();
        this.bLast = bTeamScore.getValue();
    }
}
layout文件:
<?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">
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
        <Button
            android:id="@+id/button1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:background="@android:color/holo_red_light"
            android:onClick="@{()->viewModel.aTeamAdd(1)}"
            android:shadowColor="@android:color/background_light"
            android:text="@string/button1"
            android:textColor="#FFFFFF"
            app:layout_constraintBottom_toTopOf="@+id/guideline9"
            app:layout_constraintEnd_toStartOf="@+id/guideline3"
            app:layout_constraintHorizontal_bias="0.423"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline8"
            app:layout_constraintVertical_bias="0.564" />
        <Button
            android:id="@+id/button4"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="8dip"
            android:background="@color/colorAccent"
            android:onClick="@{()->viewModel.bTeamAdd(1)}"
            android:shadowColor="@android:color/background_light"
            android:text="@string/button1"
            android:textColor="#FFFFFF"
            app:layout_constraintBottom_toTopOf="@+id/guideline9"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="@+id/guideline3"
            app:layout_constraintTop_toTopOf="@+id/guideline8"
            app:layout_constraintVertical_bias="0.564" />
        <Button
            android:id="@+id/button2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:background="@android:color/holo_red_light"
            android:onClick="@{()->viewModel.aTeamAdd(2)}"
            android:shadowColor="@android:color/background_light"
            android:text="@string/button2"
            android:textColor="#FFFFFF"
            app:layout_constraintBottom_toTopOf="@+id/guideline10"
            app:layout_constraintEnd_toStartOf="@+id/guideline3"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline9" />
        <Button
            android:id="@+id/button3"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:background="@android:color/holo_red_light"
            android:onClick="@{()->viewModel.aTeamAdd(3)}"
            android:shadowColor="@android:color/background_light"
            android:text="@string/button3"
            android:textColor="#FFFFFF"
            app:layout_constraintBottom_toTopOf="@+id/guideline11"
            app:layout_constraintEnd_toStartOf="@+id/guideline3"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline10" />
        <Button
            android:id="@+id/button6"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:background="@color/colorAccent"
            android:onClick="@{()->viewModel.bTeamAdd(3)}"
            android:shadowColor="@android:color/background_light"
            android:text="@string/button3"
            android:textColor="#FFFFFF"
            app:layout_constraintBottom_toTopOf="@+id/guideline11"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline3"
            app:layout_constraintTop_toTopOf="@+id/guideline10" />
        <Button
            android:id="@+id/button5"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:background="@color/colorAccent"
            android:onClick="@{()->viewModel.bTeamAdd(2)}"
            android:shadowColor="@android:color/background_light"
            android:text="@string/button2"
            android:textColor="#FFFFFF"
            app:layout_constraintBottom_toTopOf="@+id/guideline10"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline3"
            app:layout_constraintTop_toTopOf="@+id/guideline9" />
        <ImageButton
            android:id="@+id/imageButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="@string/undoButton"
            android:onClick="@{()->viewModel.undo()}"
            app:layout_constraintBottom_toTopOf="@+id/guideline12"
            app:layout_constraintEnd_toStartOf="@+id/guideline3"
            app:layout_constraintHorizontal_bias="0.8"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline11"
            app:srcCompat="@drawable/ic_undo_black_24dp" />
        <ImageButton
            android:id="@+id/imageButton2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="@string/resetButton"
            android:onClick="@{()->viewModel.reset()}"
            app:layout_constraintBottom_toTopOf="@+id/guideline12"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.2"
            app:layout_constraintStart_toStartOf="@+id/guideline3"
            app:layout_constraintTop_toTopOf="@+id/guideline11"
            app:srcCompat="@drawable/ic_refresh_black_24dp" />
        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Team A"
            android:textSize="@dimen/teamTextSize"
            app:layout_constraintBottom_toTopOf="@+id/guideline7"
            app:layout_constraintEnd_toStartOf="@+id/guideline3"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline2" />
        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Team B"
            android:textSize="@dimen/teamTextSize"
            app:layout_constraintBottom_toTopOf="@+id/guideline7"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline3"
            app:layout_constraintTop_toTopOf="@+id/guideline2" />
        <TextView
            android:id="@+id/scoreA"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(viewModel.getaTeamScore())}"
            android:textColor="@android:color/holo_red_light"
            android:textSize="@dimen/scoreTextSize"
            app:layout_constraintBottom_toTopOf="@+id/guideline8"
            app:layout_constraintEnd_toStartOf="@+id/guideline3"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/guideline7"
            tools:text="120" />
        <TextView
            android:id="@+id/scoreB"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(viewModel.getbTeamScore())}"
            android:textColor="@color/colorAccent"
            android:textSize="@dimen/scoreTextSize"
            app:layout_constraintBottom_toTopOf="@+id/guideline8"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="@+id/guideline3"
            app:layout_constraintTop_toTopOf="@+id/guideline7"
            tools:text="100" />
        <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.05" />
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.5" />
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_end="-220dp" />
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.15" />
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.35" />
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline9"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.5" />
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline10"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.65" />
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline11"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.8" />
        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline12"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.9" />
    </androidx.constraintlayout.widget.ConstraintLayout>
    <data>
        <variable
            name="viewModel"
            type="com.dongnaoedu.databinding7.MyViewModel" />
    </data>
</layout>
使用:
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        MyViewModel viewModel = new ViewModelProvider(this, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(MyViewModel.class);
        activityMainBinding.setViewModel(viewModel);
        activityMainBinding.setLifecycleOwner(this); //一定要加入这个,否则livedata无效(改变了livedata的值也反馈不到UI上)
    }
}




















