• 记录每天学习的新知识:DataBinding


    前言

    Jetpack 是一个丰富的组件库,它的组件库按类别分为 4 类,分别是架构(Architecture)、界面(UI)、 行为(behavior)和基础(foundation)。

    每个组件都可以单独使用,也可以配合在一起使-用。每个组件都给用户提供了一个标准, 能够帮助开发者遵循最佳做法,减少样板代码并编写可在各种 Android 版本和设备中一致运行的代码,让开发者能够集中精力编写重要的业务代码。

    在这里插入图片描述

    DataBinding 是 Google 在 Jetpack 中推出的一款数据绑定的支持库,利用该库可以实现在页面组件中直接绑定应用程序的数据源。使其维护起来更加方便,架构更明确简介。

    使用前需要了解

    运行环境:
    Android Studio Chipmunk | 2021.2.1 Patch 1
    Build #AI-212.5712.43.2112.8609683, built on May 19, 2022
    Runtime version: 11.0.12+7-b1504.28-7817840 amd64

    • 应用DataBinding,在App的build.gradle:
    android {
        buildFeatures {
    //        viewBinding = true
            dataBinding = true
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 想在哪个页面使用DataBinding,就修改对应的布局文件
      添加 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">
    
    	// .... 布局内容
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    
    </layout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 编译后就会有对应布局的binding了
        ActivityMainBinding mBinding;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    //        setContentView(R.layout.activity_main);
    
    //        mBinding = ActivityMainBinding.inflate(getLayoutInflater());
    //        setContentView(mBinding.getRoot());
    
           mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    注意:DataBinding实现了ViewBinding ,所以ViewBinding的用法也适用。

    一、基础用法

    当前事例实现:

    • 向XML中设置指定的Data格式数据,提供给View引用
    • 向XML设置点击事件
    • 向XML设置方法所在类,调用静态方法
    • 引用string资源文件

    XML

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
    
        <data>
            <!--提供方法的类-->
            <import type="com.yoshin.kt.demo_databinding.StringUtils" />
            <!--点击事件-->
            <import type="com.yoshin.kt.demo_databinding.MainActivity.Listener" />
            <!--实体类-->
            <variable
                name="student"
                type="com.yoshin.kt.demo_databinding.bean.Student" />
            <!--实体类-->
            <variable
                name="student2"
                type="com.yoshin.kt.demo_databinding.bean.Student" />
            <!--点击事件-->
            <variable
                name="lintener"
                type="Listener" />
        </data>
    
        <!--我的布局文件-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            tools:context=".MainActivity">
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:gravity="center"
                android:text="你好 世界!" />
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:gravity="center"
                android:onClick="@{()->lintener.onClick(student)}"
                android:text="@{@string/student_name + student.name,default = 小明}"
                android:textColor="@color/teal_200" />
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:gravity="center"
                android:text="@{StringUtils.getAge(student.year)}"
                android:textColor="@color/teal_200" />
    
            <EditText
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:afterTextChanged="@{lintener.afterStudentNameChanged}"
                android:gravity="center"
                android:text="@{@string/student_2 + @string/student_name + student2.name,default = 小明}"
                android:textColor="@color/teal_200" />
    
        </LinearLayout>
    
    </layout>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    Activity

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            ActivityMainBinding mBinding = ActivityMainBinding.inflate(getLayoutInflater());
            setContentView(mBinding.getRoot());
    
            Student student = new Student();
            student.setName("小黑");
            student.setYear("18");
    
            Student student2 = new Student();
            student2.setName("小绿");
    
            mBinding.setStudent(student);
            mBinding.setStudent2(student2);
    
            mBinding.setLintener(new Listener());
    
        }
    
    
        public class Listener {
    
            public void onClick(Student student) {
                Toast.makeText(MainActivity.this, student.getName(), Toast.LENGTH_SHORT).show();
            }
    
            public void afterStudentNameChanged(Editable editable) {
                Toast.makeText(MainActivity.this, editable.toString(), Toast.LENGTH_SHORT).show();
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    此时的写法,数据没有绑定

    在这里插入图片描述

    二、引入布局(include、viewStub)

    以 include 为例(DataBinding不支持merge标签):

    view_include_patriarch.xml

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
    
        <data>
    
            <variable
                name="patriarch"
                type="com.yoshin.kt.demo_databinding.bean.Patriarch" />
        </data>
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:gravity="center"
                android:text="@{@string/str_name + patriarch.name,default = 小明的爸爸}"
                android:textColor="@color/teal_200" />
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    
    </layout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:binding="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools">
    
        <data>
            <!--提供方法的类-->
            <import type="com.yoshin.kt.demo_databinding.StringUtils" />
            <!--点击事件-->
            <import type="com.yoshin.kt.demo_databinding.MainActivity.Listener" />
    
            <!--实体类-->
            <variable
                name="student"
                type="com.yoshin.kt.demo_databinding.bean.Student" />
            <!--实体类-->
            <variable
                name="student2"
                type="com.yoshin.kt.demo_databinding.bean.Student" />
    
            <!--点击事件-->
            <variable
                name="lintener"
                type="Listener" />
    
        </data>
    
        <!--我的布局文件-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            tools:context=".MainActivity">
    
    		...<include
                android:id="@+id/ic_patriarch"
                layout="@layout/view_include_patriarch"
                binding:patriarch="@{student.patriarch}" />
    
        </LinearLayout>
    
    </layout>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    需要在main.xml里添加:

        xmlns:binding="http://schemas.android.com/apk/res-auto"
    
    • 1

    但是鼓捣了半天都引用不到属性

    在这里插入图片描述
    不过没有关系!!!硬写吧,是好用的~ 这应该是个BUG吧

    参考:dataBinding中使用include :https://blog.csdn.net/chuyouyinghe/article/details/124354463

    三、单向绑定 (Data变化通知View)

    如下事例延续上面的操作续写

    1、BaseObservable

    public class Student extends BaseObservable {
    
        @Bindable
        private String name;
    
        @Bindable
        private String year;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getYear() {
            return year;
        }
    
        public void setYear(String year) {
            this.year = year;
            notifyPropertyChanged(BR.year);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    如上,如果通过 setYear(String year) 方法设置 year时,如果数据有变化就会通知View进行更新,通过重写 TextView.setText()方法确认了这一点,如果数据无变换不会通知到View更新;
    setName(String name) 调用不会通知View更新,因为没有调用到 notifyPropertyChanged(id)

    • @Bindable
      需要使用到更新的Key,需要添加此注解

    • notifyPropertyChanged(int fieldId)
      如果个Key,数据改变,就更新View

    • notifyChange()
      刷新所有Key

    2、ObservableField

    参考 :Android 安卓DataBinding(四)·单向绑定 ObservableField:https://blog.csdn.net/qq_40881680/article/details/101847386

    续写测试ObservableField

    参考上面做的,我这里也不好使啊,记一下!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!不好使!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    public class Student extends BaseObservable {
    
        private final ObservableField<String>  name = new ObservableField<>();
    
        private final ObservableField<String> year = new ObservableField<>();
    
        private final ObservableField<Patriarch> patriarch = new ObservableField<>();
    
    
        public String getName() {
            return name.get();
        }
    
        public void setName(String name) {
            this.name.set(name);
        }
    
        public String getYear() {
            return year.get();
        }
    
        public void setYear(String year) {
            this.year.set(year);
        }
    
        public Patriarch getPatriarch() {
            return patriarch.get();
        }
    
        public void setPatriarch(Patriarch patriarch) {
            this.patriarch.set(patriarch);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    在调用如下代码时,XML没有跟着实时刷新啊,(⊙o⊙)…不理解源码的痛

    student.setYear(String.valueOf(System.currentTimeMillis()));
    
    • 1
    public class Patriarch {
    
        /**
         * 继承 BaseObservableField 父类继承 BaseObservable 实现 Observable
         */
        private ObservableField<String> name;
        private ObservableInt intId;
        private ObservableLong longId;
        private ObservableDouble doubleId;
        private ObservableBoolean isOk;
        private ObservableByte oByte;
        private ObservableFloat floatId;
        private ObservableChar charId;
        private ObservableShort shortId;
    
        public Patriarch() {
            name = new ObservableField<>();
        }
    
        /**
         * 继承 ObservableField
         */
        private ObservableParcelable<Friend> friend;
    
        public String getName() {
            return name.get();
        }
    
        public void setName(String name) {
            this.name.set(name);
        }
    
        /**
         * 继承 List
         */
        ObservableList<String> list;
        ObservableArrayList<String> arrayList;
    
        /**
         * 继承 Map
         */
        ObservableMap<String, String> map;
        ObservableArrayMap<String, String> arrayMap;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    先这样吧 。没好使。

    四、双向绑定 (Data变化通知View,View变化反馈给数据)

            <TextView
                android:id="@+id/tv_2"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:gravity="center"
                android:onClick="@{()->lintener.onClick(student)}"
                android:text="@={student.name,default = 小明}"
                android:textColor="@color/teal_200" />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    如上,即双向绑定的写法

    @={student.name,default = 小明}
    
    • 1

    区别于正常写法,需要多写个=

    注意是,如果写了“=”就不能直接引用string文件了,也不能引用静态方法。

    测试的时候,配合的是 标题三、单向绑定,中的 1.BaseObservable进行的测试,验证双向绑定OK

    五、配合LiveData的写法

    1、事例延续上面代码修改,做双向绑定

    • ViewModel
    public class MainViewModel extends AndroidViewModel {
    
        public MainViewModel(@NonNull Application application) {
            super(application);
        }
    
        final MutableLiveData<Student> mutableLiveData = new MutableLiveData<>();
    
        public MutableLiveData<Student> getMutableLiveData() {
            return mutableLiveData;
        }
    
        public void setMutableLiveData(Student student) {
            mutableLiveData.setValue(student);
        }
    
    
        final MutableLiveData<String> stringMutableLiveData = new MutableLiveData<>();
    
        public MutableLiveData<String> getStringMutableLiveData() {
            return stringMutableLiveData;
        }
    
        public void setStringMutableLiveData(String str) {
            stringMutableLiveData.setValue(str);
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • XML
    
        <data>
    
    		....<variable
                name="viewModel"
                type="com.yoshin.kt.demo_databinding.MainViewModel" />
    
        <!--我的布局文件-->
        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                tools:context=".MainActivity">
    			
    			...<EditText
                    android:id="@+id/tv_1"
                    android:layout_width="match_parent"
                    android:layout_height="50dp"
                    android:gravity="center"
                    android:onClick="@{()->lintener.onClick(student)}"
                    android:text="@={viewModel.mutableLiveData.name}"
                    android:textColor="@color/teal_200" />
    
    
                <com.yoshin.kt.demo_databinding.MyTextView
                    android:id="@+id/tv_2"
                    android:layout_width="match_parent"
                    android:layout_height="50dp"
                    android:gravity="center"
                    android:text="@={viewModel.stringMutableLiveData}"
                    android:textColor="@color/teal_200" />
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 调用
    public class MainActivity extends AppCompatActivity {
    
        private static final String TAG = "MainActivity";
        ActivityMainBinding mBinding;
    
        private MainViewModel mVM
                = ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication()).create(MainViewModel.class);
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
    		... 略
    
    	    mBinding.setLifecycleOwner(this);
            mBinding.setViewModel(mVM);
    
            mVM.getMutableLiveData().observe(this, new Observer<Student>() {
                @Override
                public void onChanged(Student student) {
                    Log.i(TAG, " getMutableLiveData observe  == " + new Gson().toJson(student));
                }
            });
    
            mVM.setMutableLiveData(student);
    
            mVM.getStringMutableLiveData().observe(this, new Observer<String>() {
                @Override
                public void onChanged(String s) {
                    Log.i(TAG, " getStringMutableLiveData observe  == " + new Gson().toJson(s));
                }
            });
    
            mVM.setStringMutableLiveData("这就是个String");
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    如此,可以实现双向绑定。

    虽然实现了双向绑定,但是还有需要说的地方:
    LiveData 的泛型 TJavaBean 还是String 类型,影响观察者模式的回调

    1. TStudent (JavaBean)

    调用 mVM.setMutableLiveData(student); ,日志 getMutableLiveData observe == xxx 只会输出一次,无论值本身地址变化,还是内部数据变化;
    调用 mBinding.tv1.setText(“xxxx”); ,日志 getMutableLiveData observe == xxx 不会输出,但是值本身是变化的(通过点击按钮打印,mutableLiveData 内部值是变化的)。

    1. TString

    进入页面第一次调用 mVM.setStringMutableLiveData(str); ,日志 getStringMutableLiveData observe == xxx 会输出一次;
    之后,调用 mVM.setStringMutableLiveData(str); ,如果值是有变化的,日志 getStringMutableLiveData observe == xxx 会输出两次,重写了TextView,发现setText()的方法,夹在中间;
    如下:

     14:10:29.827 14131-14131/com.yoshin.kt.demo_databinding I/MainActivity:  getStringMutableLiveData observe  == "setString 修改后String的值"
     14:10:29.829 14131-14131/com.yoshin.kt.demo_databinding I/Main-MyTextView: setText
     14:10:29.832 14131-14131/com.yoshin.kt.demo_databinding I/MainActivity:  getStringMutableLiveData observe  == "setString 修改后String的值"
    
    • 1
    • 2
    • 3

    如果值没有变化,日志 getStringMutableLiveData observe == xxx 会输出一次;

    调用 mBinding.tv2.setText(“xxxx”); ,日志 getStringMutableLiveData observe == xxx 会输出一次。

    综上所述,推荐使用当 T(JavaBean) 的方式,容易控制。

    2、引入布局场景

    二、引入布局(include、viewStub)的写法在这就失效了,这里就要修改了,如下即可:

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
    
        <data>
            <variable
                name="viewModel"
                type="com.yoshin.kt.demo_databinding.MainViewModel" />
            <variable
                name="patriarch"
                type="com.yoshin.kt.demo_databinding.bean.Patriarch" />
        </data>
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:gravity="center"
                android:text="@{@string/str_name + viewModel.mutableLiveData.patriarch.name,default = 小明的爸爸}"
                android:textColor="@color/teal_200" />
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    
    </layout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    改成 传入 viewModel,就可以在数据改变的时候View更新。

    六、BindingAdapter

    用途: 支持自定义属性,或者是修改原有属性

    • 自定义属性

    一个参数的

    public class ImageBindingAdapter {
    
        @BindingAdapter("imageUrl")
        public static void setImageUrl(ImageView view, String url) {
            Log.i(TAG, "setImageUrl: ");
            Glide.with(view).load(url).into(view);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
                <ImageView
                    imageUrl="@{viewModel.mutableLiveData.url}"
                    android:layout_width="100dp"
                    android:layout_height="100dp"/>
    
    • 1
    • 2
    • 3
    • 4

    多个参数的

    @BindingAdapter(value = {"imageUrl", "placeholder", "error"},requireAll = false)
    public static void loadImage(ImageView view, String url, Drawable placeholder, Drawable error) {
        RequestOptions options = new RequestOptions();
        options.placeholder(placeholder);
        options.error(error);
        Glide.with(view).load(url).apply(options).into(view);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
     <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginTop="10dp"
        app:imageUrl="@{`https://goss.veer.com/creative/vcg/veer/800water/veer-136599950.jpg`}"
        app:placeholder="@{@drawable/icon}"/>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 修改属性
    public class TextViewAdapter {
        @BindingAdapter("android:text")
        public static void setText(TextView view, CharSequence text) {
            //省略特殊处理...
            String txt = text.toString().toLowerCase();
            view.setText(txt);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
            <!--使用dataBinding的TextView-->
            <TextView
                android:id="@+id/tvData"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:background="#a37c7c"
                android:text="@{`这是TextView...`}"
                android:textSize="16sp" />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这么写完,databinding都会调用这个方法,不推荐

    转 Android Jetpack组件之BindingAdapter详解:https://blog.csdn.net/jzman/article/details/106699816

    七、BindingConversion

    Android Jetpack组件之BindingAdapter详解:https://blog.csdn.net/jzman/article/details/106699816

    Android DataBinding 从入门到进阶,看这一篇就够:https://blog.csdn.net/Eqiqi/article/details/121670801

    八、支持的运算符和关键字

    绑定表达式支持的运算符和关键字

    算术运算符 + - / * %
    字符串连接运算符 +
    逻辑运算符 && ||
    二元运算符 & | ^
    一元运算符 + - ! ~
    移位运算符 >> >>> <<
    比较运算符 == > < >= <=(请注意,< 需要转义为 <)
    instanceof
    分组运算符 ()
    字面量运算符 - 字符、字符串、数字、null
    类型转换
    方法调用
    字段访问
    数组访问 []
    三元运算符 ?:
    Null 合并运算符 ??
    属性引用.
    集合操作[],可用于数组,列表,映射;
    字面常量
    资源@,但是有些资源类型需要显式指明;

    Android-DataBinding-使用-高阶:https://www.jianshu.com/p/b5762e72f56f

    参考地址

    Android DataBinding 从入门到进阶,看这一篇就够:https://blog.csdn.net/Eqiqi/article/details/121670801

    https://wenku.baidu.com/view/0a12a6356f175f0e7cd184254b35eefdc8d31592.html

    https://developer.android.google.cn/jetpack/androidx/releases/databinding

    转自 Android Jetpack架构全家桶,学完可从零搭建一个Android项目架构:http://px.sxjnk.cn/enjoy/advertorial/article_6

  • 相关阅读:
    深度学习OCR中文识别 - opencv python 计算机竞赛
    排序算法之【快速排序】
    QPushButton样式设置
    UNIAPP之js/nvue混淆探索
    leetcode做题笔记167. 两数之和 II - 输入有序数组
    论算法是如何优化的:四数之和
    C/C++实现简单高并发http服务器
    它让你1小时精通RabbitMQ消息队列、且能扛高并发
    Java实操避坑指南三、java线程安全
    SpringBoot 集成 Nacos
  • 原文地址:https://blog.csdn.net/weixin_35691921/article/details/126173976