Android DataBinding 你好!

本文来自阿钟的投稿,阅读大约15分钟

一:使用DataBinding的第一步,只需要在app/build.gradle开启它

 1android {
 2    compileSdkVersion 28
 3    defaultConfig {
 4        applicationId "azhon.com.viewbinding"
 5        //....
 6    }
 7    //开启dataBinding
 8    dataBinding {
 9        enabled = true
10    }
11}

二:将布局文件根元素修改为

 1<?xml version="1.0" encoding="utf-8"?>
 2<layout xmlns:android="http://schemas.android.com/apk/res/android"
 3    xmlns:app="http://schemas.android.com/apk/res-auto"
 4    xmlns:tools="http://schemas.android.com/tools">
 5
 6    <data>
 7
 8        <import />
 9
10        <variable />
11    </data>
12
13    <!-- layout 下只能有一个子节点 -->
14
15    <LinearLayout
16        android:layout_width="match_parent"
17        android:layout_height="match_parent">
18        <!-- 布局内容 -->
19
20    </LinearLayout>
21</layout>

在布局文件中我们可以通过快捷修复来将布局文件自动修改为符合databinding的布局

在这里插入图片描述

需要注意的是:layout 下只能有一个子节点

三:下面通过一些实例来介绍具体的使用

①为TextView绑定一个UserName

首先需要在xml中指定variable数据,然后在TextView进行绑定,如下:

 1<?xml version="1.0" encoding="utf-8"?>
 2<layout xmlns:android="http://schemas.android.com/apk/res/android"
 3    xmlns:app="http://schemas.android.com/apk/res-auto"
 4    xmlns:tools="http://schemas.android.com/tools">
 5
 6    <data>
 7        <!-- 指定数据 -->
 8        <variable
 9            name="userName"
10            type="String" />
11    </data>
12
13    <LinearLayout
14        android:layout_width="match_parent"
15        android:layout_height="match_parent">
16
17        <TextView
18            android:layout_width="match_parent"
19            android:layout_height="40dp"
20            android:gravity="center"
21            android:text="@{userName,default=我是默认的值}"
22            android:textColor="#333333" />
23    </LinearLayout>
24</layout>

在Activity中对这个布局加载,然后在设置userName的值

1public class FirstMainActivity extends AppCompatActivity {
2    @Override
3    protected void onCreate(@Nullable Bundle savedInstanceState) {
4        super.onCreate(savedInstanceState);
5        FirstMainBinding dataBinding = DataBindingUtil.setContentView(this, R.layout.first_main);
6        //设置数据
7        dataBinding.setUserName("Hello 阿钟");
8    }
9}

1、Activity加载布局需要使用DataBindingUtil.setContentView(),然后返回当前布局的*Binding对象,此类的命名规则为布局文件名称的驼峰命名加上Binding:如activity_main则为ActivityMainBinding
2、在布局中都是通过@{}来进行引用变量、数据等
3、如果需要对字符串进行拼接的话就需要这样子写'@{"拼接字符串"+userName}'

②当然在布局中也是可以直接使用List、Map等
 1<?xml version="1.0" encoding="utf-8"?>
 2<layout xmlns:android="http://schemas.android.com/apk/res/android"
 3    xmlns:app="http://schemas.android.com/apk/res-auto"
 4    xmlns:tools="http://schemas.android.com/tools">
 5
 6    <data>
 7        <!--引入数据类型-->
 8        <import type="java.util.List" />
 9        <import type="java.util.Map" />
10
11        <!--与元素类型 "variable" 相关联的 "type" 属性值不能包含 '<' 字符。
12        这里 < 需要被转义为 &lt;-->
13        <variable
14            name="list"
15            type="List&lt;String>" />
16        <variable
17            name="map"
18            type="Map&lt;String,String>" />
19    </data>
20
21    <LinearLayout
22        android:layout_width="match_parent"
23        android:layout_height="match_parent">
24
25        <!--取list集合中的第一个元素-->
26        <TextView
27            android:layout_width="match_parent"
28            android:layout_height="wrap_content"
29            android:text="@{list[0]}"/>
30        <!--取map集合中key = "key"元素-->
31        <TextView
32            android:layout_width="match_parent"
33            android:layout_height="wrap_content"
34            android:text='@{map.get("key")}' />
35    </LinearLayout>
36</layout>
然后通过当前布局文件的Binding对`List`、`Map`进行赋值,如下:
 1public class FirstMainActivity extends AppCompatActivity {
 2    @Override
 3    protected void onCreate(@Nullable Bundle savedInstanceState) {
 4        super.onCreate(savedInstanceState);
 5        FirstMainBinding dataBinding = DataBindingUtil.setContentView(this, R.layout.first_main);
 6        //设置数据
 7        dataBinding.setList(Arrays.asList("Larry", "Moe", "Curly"));
 8        HashMap<String, String> map = new HashMap<>();
 9        map.put("key", "我是map的值");
10        dataBinding.setMap(map);
11    }
12}
③对View进行`onClick`事件绑定
 1<?xml version="1.0" encoding="utf-8"?>
 2<layout xmlns:android="http://schemas.android.com/apk/res/android"
 3    xmlns:app="http://schemas.android.com/apk/res-auto"
 4    xmlns:tools="http://schemas.android.com/tools">
 5
 6    <data>
 7        <variable
 8            name="model"
 9            type="com.azhon.viewbinding.FirstMainActivity" />
10    </data>
11
12    <LinearLayout
13        android:layout_width="match_parent"
14        android:layout_height="match_parent">
15        <!--第一种写法-->
16        <TextView
17            android:layout_width="match_parent"
18            android:layout_height="wrap_content"
19            android:onClick="@{model::click}"/>
20        <!--第二种写法-->
21        <TextView
22            android:layout_width="match_parent"
23            android:layout_height="wrap_content"
24            android:onClick="@{model.click}"/>
25        <!--第三种写法-->
26        <TextView
27            android:layout_width="match_parent"
28            android:layout_height="wrap_content"
29            android:onClick="@{()-> model.click2()}"/>   
30        <!--第四种写法 调用有参数的函数-->
31        <!--theView 指代当前的TextView-->
32        <TextView
33            android:layout_width="match_parent"
34            android:layout_height="wrap_content"
35            android:onClick="@{(thisView)-> model.click3(thisView,12)}"/>
36    </LinearLayout>
37</layout>
相对应的Activity代码
 1public class MainActivity extends AppCompatActivity {
 2
 3     @Override
 4     protected void onCreate(@Nullable Bundle savedInstanceState) {
 5         super.onCreate(savedInstanceState);
 6         FirstMainBinding dataBinding = DataBindingUtil.setContentView(this, R.layout.first_main);
 7         //对model进行赋值
 8         mainBinding.setModel(this);
 9     }
10
11     public void click(View view) {
12        Toast.makeText(this, "DataBinding点击事件", Toast.LENGTH_SHORT).show();
13     }
14     public void click2() {
15         Toast.makeText(this, "DataBinding点击事件(无参数)", Toast.LENGTH_SHORT).show();
16     }
17     public void click3(View view, int p) { 
18         Toast.makeText(this, "DataBinding点击事件,参数:" + p, Toast.LENGTH_SHORT).show();
19     }
20}
④在布局中进行少量的运算,所支持的运算符如下:

!=%+-*/<>==<=>=<<>>>>>

或者使用三目运算符show ? View.VISIBLE : View.GONE

 1<?xml version="1.0" encoding="utf-8"?>
 2<layout xmlns:android="http://schemas.android.com/apk/res/android"
 3    xmlns:app="http://schemas.android.com/apk/res-auto"
 4    xmlns:tools="http://schemas.android.com/tools">
 5
 6    <data>
 7        <!--导入View类-->
 8        <import type="android.view.View" />
 9    </data>
10
11    <LinearLayout
12        android:layout_width="match_parent"
13        android:layout_height="match_parent">
14
15        <TextView
16            android:layout_width="match_parent"
17            android:layout_height="wrap_content"
18            android:text="@{String.valueOf(index + 1)}"
19            android:visibility="@{age > 13 ? View.GONE : View.VISIBLE}"
20            android:transitionName='@{"image_" + id}'/>
21    </LinearLayout>
22</layout>

四:dataBinding结合RecyclerView进行使用

①布局文件中添加RecyclerView

 1<?xml version="1.0" encoding="utf-8"?>
 2<layout xmlns:android="http://schemas.android.com/apk/res/android"
 3    xmlns:app="http://schemas.android.com/apk/res-auto"
 4    xmlns:tools="http://schemas.android.com/tools">
 5
 6    <data>
 7
 8    </data>
 9
10    <LinearLayout
11        android:layout_width="match_parent"
12        android:layout_height="match_parent"
13        android:orientation="vertical">
14
15        <android.support.v7.widget.RecyclerView
16            android:id="@+id/rv"
17            android:layout_width="match_parent"
18            android:layout_height="match_parent" />
19    </LinearLayout>
20</layout>

②创建一个实体类,用来做为RecyclerView的数据源User

 1public class User  {
 2    private String userName;
 3    private String userNum;
 4
 5    public String getUserName() {
 6        return userName;
 7    }
 8
 9    public void setUserName(String userName) {
10        this.userName = userName;
11    }
12
13    public String getUserNum() {
14        return userNum;
15    }
16
17    public void setUserNum(String userNum) {
18        this.userNum = userNum;
19    }
20}

③编写RecyclerView的Item布局,引入User这个实体类

 1<?xml version="1.0" encoding="utf-8"?>
 2<layout xmlns:android="http://schemas.android.com/apk/res/android">
 3
 4    <data>
 5        <!-- Item的数据源为User -->
 6        <variable
 7            name="user"
 8            type="com.azhon.viewbinding.User" />
 9    </data>
10
11    <LinearLayout
12        android:layout_width="match_parent"
13        android:layout_height="wrap_content"
14        android:background="#eeeeee"
15        android:gravity="center_vertical"
16        android:orientation="vertical"
17        android:paddingHorizontal="16dp"
18        android:paddingVertical="8dp">
19
20        <TextView
21            android:id="@+id/tv_name"
22            android:layout_width="wrap_content"
23            android:layout_height="wrap_content"
24            android:text='@{"姓名:"+user.userName,default=阿钟}' />
25
26        <TextView
27            android:id="@+id/tv_num"
28            android:layout_width="wrap_content"
29            android:layout_height="wrap_content"
30            android:text='@{"序号:"+user.userNum,default=123456}' />
31    </LinearLayout>
32</layout>

④结合DataBinding创建RecycleerView适配器

 1public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyViewHolder> {
 2
 3    private List<User> users;
 4    private Context context;
 5
 6    public TestAdapter(List<User> users, Context context) {
 7        this.users = users;
 8        this.context = context;
 9    }
10
11    @NonNull
12    @Override
13    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
14        LayoutInflater inflater = LayoutInflater.from(context);
15        ItemRvBinding binding = DataBindingUtil.inflate(inflater, R.layout.item_rv, parent, false);
16        return new MyViewHolder(binding.getRoot());
17    }
18
19    @Override
20    public void onBindViewHolder(@NonNull MyViewHolder holder, int i) {
21        ItemRvBinding binding = DataBindingUtil.getBinding(holder.itemView);
22        binding.setUser(users.get(i));
23        //迫使数据立即绑定
24        binding.executePendingBindings();
25    }
26
27    @Override
28    public int getItemCount() {
29        return users.size();
30    }
31
32    public class MyViewHolder extends RecyclerView.ViewHolder {
33        public MyViewHolder(View itemView) {
34            super(itemView);
35        }
36    }
37
38}

通过DataBindingUtil.inflate()加载Item的布局,返回Item的*Binding对象
onBindViewHolder中设置Item的数据binding.setUser(users.get(i));需要调用
binding.executePendingBindings();对数据进行立即绑定,防止数据错乱

⑤接下来就简单了,为Adapter设置数据即可

 1FirstMainBinding dataBinding = DataBindingUtil.setContentView(this, R.layout.first_main);
 2//通过dataBinding找到布局View
 3RecyclerView recyclerView = dataBinding.rv;
 4recyclerView.setLayoutManager(new LinearLayoutManager(this));
 5List<User> users = new ArrayList<>();
 6for (int i = 0; i < 30; i++) {
 7    User user = new User();
 8    user.setUserName("用户 " + i);
 9    user.setUserNum(String.valueOf(Math.round(Math.random()) * 100000));
10    users.add(user);
11}
12TestAdapter adapter = new TestAdapter(users, this);
13recyclerView.setAdapter(adapter);

好了基本的一些DataBinding使用到这里就说完了,感兴趣的大伙可以自己动手实践一下

我创建了一个关于Android的交流群,有兴趣可以加我微信我拉你

 

             

 

如果感觉现在的网络技术文章质量不高,苦于自己的Android技术无法得到明显的提升,感叹没有一帮好的学习伙伴及道友,那么我的知识星球可能就是一片净土,好的学习气氛,更好的技术资源与文章,自由且高效率,快来吧。

 

       

点击阅读原文,获得更多精彩内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值