这一篇Databinding应该可以帮助迅速上手吧

news2024/11/20 4:34:37

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上)

    }
}

在这里插入图片描述

其他用法:前往官网

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/491934.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JAVAEE】创建线程的方式及线程的常用方法

目录 1.创建线程的四种方式 1.1继承Thread类 1.2实现Runnable接口 1.3匿名内部类 1.4lambda表达式 2.多线程的优势-增加运行速度 3.Thread类及常用方法 3.1构造方法 3.2常见属性 演示后台线程 演示线程是否存活 3.3线程中断 3.4线程等待-join() 3.5获取当前线程 …

23年5月高项备考学习笔记——信息系统管理

管理&#xff1a;监督系统的设计和结构 系统&#xff1a;提供蓝图 系统管理&#xff1a; 规划和组织&#xff1a;业务战略、组织机制、信息系统 业务战略&#xff1a; 总成本领先战略 差异性战略 专注化战略 设计和实施&#xff1a;战略转成需求&#xff0c;便管理&#xff1b…

5月5号软件资讯更新合集.....

Visual Studio Code 1.78 发布 VS Code 1.78 已发布&#xff0c;此版本一些主要亮点包括&#xff1a; 辅助功能改进 - 更好的屏幕阅读器支持、新的音频提示。 新的颜色主题 - “Modern” 浅色和深色主题默认设置。 配置文件模板 - Python、Java、数据科学等的内置模板。 新…

2023年6月DAMA-CDGA/CDGP数据治理认证报名请尽早啦!

6月18日DAMA-CDGA/CDGP数据治理认证考试开放报名中&#xff01; 考试开放地区&#xff1a;北京、上海、广州、深圳、长沙、呼和浩特、杭州、南京、济南、成都、西安。其他地区凑人数中… DAMA-CDGA/CDGP数据治理认证开班时间&#xff1a;5月7日 DAMA认证为数据管理专业人士提供…

线上FullGC问题排查实践——手把手教你排查线上问题 | 京东云技术团队

作者&#xff1a;京东科技 韩国凯 一、问题发现与排查 1.1 找到问题原因 问题起因是我们收到了jdos的容器CPU告警&#xff0c;CPU使用率已经达到104% 观察该机器日志发现&#xff0c;此时有很多线程在执行跑批任务。正常来说&#xff0c;跑批任务是低CPU高内存型&#xff0c…

【马蹄集】第九周作业

第九周作业 目录 MT2125 一样的虫子MT2126 AB数对MT2127 权值计算MT2128 黑客小码哥MT2129 来给单词分类 MT2125 一样的虫子 难度&#xff1a;黄金    时间限制&#xff1a;1秒    占用内存&#xff1a;128M 题目描述 有 N 只虫子&#xff0c;每只虫子有6条腿&#xff0c;每…

通过Python的pytesseract库识别图片中的文字

文章目录 前言一、pytesseract1.pytesseract是什么&#xff1f;2.安装pytesseract3.查看pytesseract版本4.安装PIL5.查看PIL版本 二、Tesseract OCR1.Tesseract OCR是什么&#xff1f;2.安装Tesseract OCR3.安装 Tesseract OCR 语言包 三、使用方法1.引入库2.打开图片文件3.使用…

聊一聊 Valgrind 监视非托管内存泄露和崩溃

一&#xff1a;背景 1. 讲故事 只要是程序总会出现各种莫名其妙的问题&#xff0c;比如&#xff1a;非托管内存泄露&#xff0c;程序崩溃&#xff0c;在 Windows 平台上一般用微软自家的官方工具 App Verifier 就可以洞察&#xff0c;那问题出在 Linux 上怎么办呢&#xff1f…

块状链表实现BigString大字符串操作(golang)

前言 块状链表是介于链表和数组之间的数据结构&#xff0c;能够在 O ( n ) O(\sqrt{n}) O(n ​)时间内完成插入、删除、访问操作。 数据结构如图所示。假设最大容量为 n n n, 则它有一个长度为 s n s\sqrt{n} sn ​的链表。链表中每个结点是一个长度为 2 n 2 \times \sqrt{…

C#_各类应用程序

目录 前言 1. 第一个程序&#xff1a;Hello&#xff0c;World&#xff01; 1.1 Console 1.2 Windows Forms 1.3 WPF&#xff08;Windows Presentation Foundation&#xff09; 1.4 ASP.NET Web Forms 1.5 ASP.NET MVC(Model - View - Controller) 1.6 Windows Store A…

Tuxera NTFS2023Mac专业NTFS驱动软件 解决Mac不能写入移动硬盘U盘问题 管理修复磁盘

Tuxera NTFS2023Mac专业NTFS驱动软件 解决Mac不能写入移动硬盘U盘问题 管理修复磁盘问题! NTFS For Mac2023是一款功能强大的MAC读写软件。NTFS For Mac可以帮助用户对磁盘进行日常管理&#xff0c;如果用户电脑的磁盘有问题&#xff0c;可以使用该软件进行修复&#xff0c;延…

Chatgpt系列(一) 如何使用chatgpt

系列文章目录 第一章: 如何使用chatgpt 第二章: chatgpt的概述 第三章: langchain入门 第四章: index 第五章: prompt 目录 系列文章目录 前言 一、LLM是什么&#xff1f; 二、使用步骤 1.学习地址 2.阅读内容重点的介绍 2.答复 读入数据 总结 系列文章目录前言一…

0基础学Java必备的50个知识点

1、编写&#xff1a;编写的Java代码保存在以“.java”结尾的源文件中。 2、编译&#xff1a;使用javac.exe命令编译java源文件&#xff0c;生成字节码文件。 格式&#xff1a;javac 源文件名.java 3、运行&#xff1a;使用java.exe命令解释运行字节码文件。格式&#xff1a;…

Linux笔记3

目录 一、root用户1.su命令2.sudo命令 二、vi/vim编译器1.三种工作模式2.命令模式3.底线命令模式 三、用户和用户组1.用户组管理2.用户管理3.getent命令 四、权限1.查看权限控制信息2.chmod 命令3.chown 命令 五、常用快捷键1.Ctrlc2.Ctrld3.历史命令4.光标移动快捷键 一、root…

亚马逊云科技和安恒信息,发布云原生SaaS主机安全和云原生堡垒机

4月19日&#xff0c;安恒信息首次举行了以“新见未来 实现梦想”为主题的年度新品发布会。来自产业界、投资界、财经界、媒体界等多方代表共同见证了本次发布会。这也是安恒信息自成立以来&#xff0c;首次大规模、高密度地发布新品。 联合产品发布 云原生SaaS主机安全与云原…

Linux 指令(一)+完整思维导图+实图例子+深入细节+通俗易懂建议收藏

绪论 在上一章&#xff0c;我们已经将Linux环境的安装起来了&#xff0c;从本章开始&#xff0c;我们将正式的进入到Linux的学习&#xff0c;Linux的学习还是比较的枯燥无味的&#xff0c;但我们要吃得苦中苦&#xff0c;让我们一起加油&#xff0c;进大厂拿到心仪的offer&…

黑马程序员-职工管理系统实战-附加源码Git

1、管理系统需求 职工管理系统可以用来管理公司内所有员工的信息 本教程主要利用C来实现一个基于多态的职工管理系统 公司中职工分为三类&#xff1a;普通员工、经理、老板&#xff0c;显示信息时&#xff0c;需要显示职工编号、职工姓名、职工岗位、以及职责 普通员工职责…

Redis在项目实践中的问题解决方案汇总

前言 无论是在开发过程中还是在准备跑路的面试过程中&#xff0c;和Redis相关的话题&#xff0c;难免会涉及到四个特殊场景&#xff1a;缓存穿透、缓存雪崩、缓存击穿以及数据一致性。 虽然在作为服务缓存层的时候Redis确实能极大减少服务端的请求压力&#xff0c;但是如果在…

企业组织管理神器:红海云可视化组织管理功能深度解析

在当前的VUCA时代&#xff0c;企业需要保持敏捷以应对变革和不确定性。组织架构作为承载战略目标的重要工具&#xff0c;如果无法敏捷调整&#xff0c;会直接影响企业战略的成功落地。但组织架构的设计和调整会触及其他业务&#xff0c;包括岗位、编制、人员与汇报关系等信息变…

优先级队列(大根堆与小根堆)

优先级队列&#xff08;大根堆与小根堆&#xff09; 文章目录 优先级队列&#xff08;大根堆与小根堆&#xff09;堆的介绍模拟堆以数组模型为例&#xff0c;创建堆向下调整&#xff08;shiftDown&#xff09;入队&#xff08;push&#xff09;及向上调整&#xff08;shiftUp&a…