美文网首页
DataBinding在Android中的使用

DataBinding在Android中的使用

作者: 放羊娃华振 | 来源:发表于2021-01-01 21:20 被阅读0次

    一、概述

    DataBinding可以实现数据单向或者双向的绑定,让开发比较方便。通过数据变化更新UI,完全由数据驱动。

    二、使用

    1、集成DataDinding

    添加 dataBinding.enabled true 和 dataBinding { enabled = true }
    示例如下:

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 30
        buildToolsVersion "30.0.1"
        defaultConfig {
            applicationId "com.stormdzh.myapplication"
            minSdkVersion 15
            targetSdkVersion 30
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            dataBinding.enabled true
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
    
        //添加这行就算引入了
        dataBinding {
            enabled = true
        }
    }
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation 'androidx.appcompat:appcompat:1.0.2'
        implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'androidx.test.ext:junit:1.1.0'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    
        implementation 'com.facebook.fresco:fresco:2.3.0'
    }
    
    2、实现xml
    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
    
        <data>
    
            <variable
                name="title"
                type="java.lang.String" />
        </data>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <TextView
                android:textColor="#000000"
                android:id="@+id/tvTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{title}"/>
        </LinearLayout>
    
    </layout>
    
    3、Activity中添加测试代码
    public class TestDataBindingActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ActivityTestDatabindingBinding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_test_databinding);
            //setContentView(R.layout.activity_test_databinding);
            viewDataBinding.setLifecycleOwner(this);
            viewDataBinding.setTitle("测试字符串");
        }
    }
    
    4、集成中问题

    1.Activity需要集成AppCompatActivity
    2.写完DataBindingUtil.setContentView(this, R.layout.activity_test_databinding)后,可以输入ActivityTestDatab...让编译器不全这个变量。这个变量是Android生成的,自己手写可能会有误差。

    三、常用知识

    1、引入对象

    需要把类引入进来,之后给他设置一个name。

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
    
        <data>
    
            <variable
                name="title"
                type="java.lang.String" />
             <variable
                 name="user"
                 type="com.stormdzh.myapplication.User" />
        </data>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <TextView
                android:textColor="#000000"
                android:id="@+id/tvTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{title}"/>
    
    
            <TextView
                android:textColor="#000000"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{user.name}"/>
        </LinearLayout>
    
    </layout>
    
    2、引入静态方法

    需要把工具类引入进来,之后通过@{AppUtil.int2Str(user.age)}调用

    public class AppUtil {
    
        public static String  int2Str(int num){
    
            return String.valueOf(num);
        }
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
    
        <data>
    
            <import type="com.stormdzh.myapplication.AppUtil" />
            <variable
                name="title"
                type="java.lang.String" />
             <variable
                 name="user"
                 type="com.stormdzh.myapplication.User" />
        </data>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <TextView
                android:textColor="#000000"
                android:id="@+id/tvTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{title}"/>
    
    
            <TextView
                android:textColor="#000000"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{user.name}"/>
    
            <TextView
                android:textColor="#000000"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{AppUtil.int2Str(user.age)}"/>
        </LinearLayout>
    
    </layout>
    
    
    3、DataBinding中引入数据的另一种形式
     <data>
            <import type="java.lang.String"/>
            <import type="com.stormdzh.myapplication.User"
                alias="User"/>
            <variable name="title" type="String" />
            <variable name="user" type="User" />
        </data>
    
    4、如何使用data中引入和定义的内容

    1.variable——使用variable中的bean对象,如果是属性,直接使用@{name.field}

    <TextView
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:text="@{user.name}" />
    

    2.如果使用的无参数方法,@{() -> name.function()}

    <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="@{() -> listener.onClickListenerBinding()}"
                android:text="@{Utility.autoAppend(v,user.name)}" />
    

    3.点击事件需要把点击的view传入并操作,@{(v) -> name.function(v)} 括号中间的v就表示当前的这个view的参数名称(可以自定义),直接作为参数名使用就可以。

    <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="@{(v) -> listener.onClickListenerBinding(v)}"
                android:text="@{user.name}" />
    
    5、DataBinding是使用点击事件
    //java代码
    public class TestDataBindingActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ActivityTestDatabindingBinding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_test_databinding);
    //        setContentView(R.layout.activity_test_databinding);
            viewDataBinding.setLifecycleOwner(this);
            viewDataBinding.setTitle("测试字符串");
    
            User user = new User();
            user.name="张三";
            user.age=18;
            viewDataBinding.setUser(user);
    
            user.name="李四";
    
            //设置点击事件
            viewDataBinding.setEventHandler(new OnEventHandler());
    
        }
    
        public class OnEventHandler{
            public void onClick(View v){
                Toast.makeText(TestDataBindingActivity.this,"响应了点击事件",Toast.LENGTH_SHORT).show();
            }
        }
    }
    
    //布局文件 
    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
    
        <data>
    
            <import type="com.stormdzh.myapplication.AppUtil" />
    
            <variable
                name="title"
                type="java.lang.String" />
    
            <variable
                name="user"
                type="com.stormdzh.myapplication.User" />
    
            <variable
                name="eventHandler"
                type="com.stormdzh.myapplication.TestDataBindingActivity.OnEventHandler" />
        </data>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <Button
                android:onClick="@{(v)->eventHandler.onClick(v)}"
                android:layout_width="match_parent"
                android:layout_height="45dp"
                android:background="#543298"
                android:gravity="center"
                android:text="更新数据"
                android:textColor="#000000" />
    
            <TextView
                android:id="@+id/tvTitle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{title}"
                android:textColor="#000000" />
    
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{user.name}"
                android:textColor="#000000" />
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{AppUtil.int2Str(user.age)}"
                android:textColor="#000000" />
        </LinearLayout>
    
    </layout>
    
    6、include使用

    系统会自动生成一个自定义属性bind,通过bind可以直接对include中的layout中绑定的数据直接进行赋值,这样就可以间接的控制include中的操作。

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:bind="http://schemas.android.com/apk/res-auto">
       <data>
           <variable name="user" type="com.example.User"/>
       </data>
       <LinearLayout
           android:orientation="vertical"
           android:layout_width="match_parent"
           android:layout_height="match_parent">
           <include layout="@layout/name"
               bind:user="@{user}"/>
           <include layout="@layout/contact"
               bind:user="@{user}"/>
       </LinearLayout>
    </layout>
    
    7、ViewStub使用

    首先ViewStub在尚未添加到xml中时,获取Bindgin对象肯定是无效的,所以需要在OnInflateListener中回调被添加的事件,然后再去获Bing对象。

    binding = DataBindingUtil.setContentView(this, R.layout.activity_view_stub);
    binding.viewStub.setOnInflateListener(new ViewStub.OnInflateListener() {
        @Override
        public void onInflate(ViewStub stub, View inflated) {
            ViewStubBinding binding = DataBindingUtil.bind(inflated);
            User user = new User("name", "刘备");
            binding.setUser(user);
        }
    });
    

    四、绑定可观察数据;绑定可观察数据由三种方式:object,field,collections。

    1、继承BaseObservable,当数据发生变化的时候调用:notifyChange方法

    public class User extends BaseObservable {
        public String name;
        public int age;
    }
    
    //模拟数据变化
    public class OnEventHandler{
            public void onClick(View v){
                Toast.makeText(TestDataBindingActivity.this,"响应了点击事件",Toast.LENGTH_SHORT).show();
                user.name="阿波罗";
                user.notifyChange();
            }
        }
    

    2、一个对象中只有一个或者几个变量需要观察变化,比如age需要变化

    public class User {
        public String name;
        //把int改为ObservableInt
        public ObservableInt age;
    }
    

    对于基本类型和Parcelable我们可以直接使用对应的包装类:

    ObservableBoolean
    ObservableByte
    ObservableChar
    ObservableShort
    ObservableInt
    ObservableLong
    ObservableFloat
    ObservableDouble
    ObservableParcelable

    之后再Activity通过修改ObservableInt的值,在调用notifyChange更新

    public class TestDataBindingActivity extends AppCompatActivity {
    
        private User user;
        ObservableInt observableAge = new ObservableInt(18);
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ActivityTestDatabindingBinding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_test_databinding);
    //        setContentView(R.layout.activity_test_databinding);
            viewDataBinding.setLifecycleOwner(this);
            viewDataBinding.setTitle("测试字符串");
    
            user = new User();
            user.name = "张三";
            user.age = observableAge;
            viewDataBinding.setUser(user);
    
            //设置点击事件
            viewDataBinding.setEventHandler(new OnEventHandler());
        }
    
        public class OnEventHandler {
            public void onClick(View v) {
                Toast.makeText(TestDataBindingActivity.this, "响应了点击事件", Toast.LENGTH_SHORT).show();
                user.name = "阿波罗";
                observableAge.set(90);
                observableAge.notifyChange();
            }
        }
    }
    
    

    四、LiveData+DataBinbing

    实体类:

    public class Person {
        public String name;
        public int age;
    }
    

    Xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
    
        <data>
    
            <variable
                name="liveData"
                type="androidx.lifecycle.MutableLiveData&lt;com.stormdzh.myapplication.Person>" />
    
            <variable
                name="eventHandler"
                type="com.stormdzh.myapplication.LiveDataEntityBindingActivity.OnEventHandler" />
        </data>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <Button
                android:onClick="@{(v)->eventHandler.onClick(v)}"
                android:layout_width="match_parent"
                android:layout_height="45dp"
                android:background="#543298"
                android:gravity="center"
                android:text="更新数据"
                android:textColor="#000000" />
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{liveData.name}"
                android:textColor="#000000" />
    
        </LinearLayout>
    </layout>
    

    java类的实现

    public class LiveDataEntityBindingActivity extends AppCompatActivity {
    
        MutableLiveData<Person> mutableLiveData;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ActivityEntityLiveDatabindingBinding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_entity_live_databinding);
            viewDataBinding.setLifecycleOwner(this);
            mutableLiveData =new MutableLiveData<>();
            //设置点击事件
            viewDataBinding.setEventHandler(new OnEventHandler());
            viewDataBinding.setLiveData(mutableLiveData);
            Person p =new Person();
            p.name= "首次";
            mutableLiveData.setValue(p);
        }
    
        public class OnEventHandler {
            public void onClick(View v) {
                Toast.makeText(LiveDataEntityBindingActivity.this, "响应了点击事件", Toast.LENGTH_SHORT).show();
                Person p =new Person();
                p.name= "更新";
                mutableLiveData.setValue(p);
            }
        }
    }
    
    

    五、双向绑定

    上述的单向绑定是数据变化后更新UI,而双向绑定是指其中任意一个变化后都会同步更新到另一个。双向绑定使用@={}表达式来实现:

    <data>
    ...
       <variable name="input" type="androidx.databinding.ObservableField&lt;String"/>
        </data>
    ...
    <EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@={input}"/>
    

    目前已经支持双向绑定的列表:


    image.png

    六、DataBinding加载图片

    Xml文件实现逻辑

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
    
        <data>
    
            <import type="com.stormdzh.myapplication.AppUtil" />
    
            <variable
                name="imageUrl"
                type="java.lang.String" />
    
            <variable
                name="eventHandler"
                type="com.stormdzh.myapplication.PicDataBindingActivity.OnEventHandler" />
        </data>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
    
            <Button
                android:layout_width="match_parent"
                android:layout_height="45dp"
                android:background="#543298"
                android:gravity="center"
                android:onClick="@{(v)->eventHandler.onClick(v)}"
                android:text="更新数据"
                android:textColor="#000000" />
    
            <com.facebook.drawee.view.SimpleDraweeView
                imageUrl="@{imageUrl}"
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="10dp" />
    
        </LinearLayout>
    </layout>
    

    java代码实现

    public class PicDataBindingActivity extends AppCompatActivity {
    
    
        ActivityPicDatabindingBinding viewDataBinding;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_pic_databinding);
    //        setContentView(R.layout.activity_test_databinding);
            viewDataBinding.setLifecycleOwner(this);
    
            //设置点击事件
            viewDataBinding.setEventHandler(new OnEventHandler());
    
            String path = "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1089874897,1268118658&fm=26&gp=0.jpg";
            viewDataBinding.setImageUrl(path);
    
        }
    
    
        public class OnEventHandler {
            public void onClick(View v) {
                Toast.makeText(PicDataBindingActivity.this, "响应了点击事件", Toast.LENGTH_SHORT).show();
    
                String path = "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1056193884,1712488622&fm=26&gp=0.jpg";
                viewDataBinding.setImageUrl(path);
            }
        }
    
        @BindingAdapter("imageUrl")
        public static void loadImage(SimpleDraweeView iv, String imageUrl) {
            Log.i("dzh", "加载图片了");
            loadPic(iv, imageUrl);
        }
    
        private static void loadPic(SimpleDraweeView mSimpleDraweeView, String path) {
    
            Uri uri = Uri.parse(path);
            mSimpleDraweeView.setImageURI(uri);
        }
    
    
    }
    

    五、总结

    DataBing还有很多知识点需要完善,但是大致的要点都介绍了。现在也都晚上9点多了,有点写不动了,以后再花点时间好好整理其中的细节,大家一起共勉!之后奉上Demo源码!

    相关文章

      网友评论

          本文标题:DataBinding在Android中的使用

          本文链接:https://www.haomeiwen.com/subject/lzbgictx.html