Android DataBinding布局的加载深入探究

Android DataBinding布局的加载深入探究

什么是DataBinding

DataBinding 是在Android数据驱动开发中增强UI绑定的一项新功能,简化了通过代码获取视图变量的步骤,同时实现了单项和双向数据绑定。

DataBinding核心类

ViewDataBinding

ViewDataBinding 是DataBinding中的核心类,它是一个抽象类,其他所有的 DataBinding 类都是它的子类。ViewDataBinding可以理解为我们绑定一个layout文件的关键类,这个类可以根据layout文件生成对应的:@Binding类。其它的Binding类只是@Binding类的继承类,主要是针对全局变量的问题进行优化。

理解Binding类

Binding类是由过你定义的xml文件(BR)自动生成,例如我们定义了一段xml片段

< TextView android:id="@+id/showname"
           android:text="@{user.name}" />

对于这段xml,会自动生成一个 Binding 类:

public abstract class ItemUserBinding extends ViewDataBinding {
    @NonNull
    public final TextView showname;
    //....  

    //这里可以看到生成的变量 showname,通过 showname 可以直接去操作对应的 View .

    protected ItemUserBinding(Object _bindingComponent, View _root, int _localFieldCount) {
        super(_bindingComponent, _root, _localFieldCount);
        final Object[] bindings = mapBindings(_root, _localFieldCount, sIncludes, sViewsWithIds);
        this.showname = (TextView) bindings[0];
    }

    //....
}

这个类包含 View 和 UI 中使用的变量与布局。当您需要更新 View 的值时,直接从生成的 Binding 类中访问它们。

DataBinding的使用

第一种使用方式:在布局文件中使用DataBinding

我们知道,在普通的布局文件中直接使用 ${ } 表达式绑定变量。在使用 DataBinding 的布局文件中:

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

在 Activity 中使用 DataBinding:

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding dataBinding; //这里为生成的ActivityMainBinding绑定类

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //获取DataBinding对象
        dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        User user = new User("hongtao", "123456");
        //将user对象与DataBinding中定义的user绑定
        dataBinding.setUser(user);
    }
}

第二种使用方式:在代码中使用DataBinding

方法一:手动引用布局并初始化DataBinding对象

ActivityMainBinding dataBinding = ActivityMainBinding.inflate(layoutInflater, null, false);
setContentView(dataBinding.getRoot());

User user = new User("hongtao", "123456");
dataBinding.setUser(user);

方法二:使用DataBinding.bind()

ActivityMainBinding dataBinding = DataBindingUtil.bind(findViewById(android.R.id.content));

User user = new User("hongtao", "123456");
dataBinding.setUser(user);

下面通过代码示例进一步了解DataBinding的使用

示例一:Button绑定监听事件

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
tools:context=".MainActivity">

    <data>
        <variable
            name="message"
            type="String" />
    </data>

    <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{() -> customOnClick()}"/>

    </LinearLayout>

</layout>
ActivityMainBinding dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
dataBinding.setMessage("Button点击");
dataBinding.setCallback(new MainActivityCallback());

class MainActivityCallback {
    public void customOnClick() {
        Toast.makeText(MainActivity.this, "Click Button!!!", Toast.LENGTH_SHORT).show();
    }
}

示例二:RecyclerView绑定数据

RecyclerView 是Android中一个通过 Adapter 提供数据并显示数据的 View。

<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <variable
            name="adapter"
            type="com.example.databinding.recyclerview.MainAdapter" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <androidx.recyclerview.widget.RecyclerView
            app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
            app:adapter="@{adapter}"
            android:layout_Width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>

</layout>
//新建一个Adapter
class MainAdapter extends RecyclerView.Adapter<MainAdapter.MyViewHolder> {
    private List<User> users;
    private Context mContext;

    public MainAdapter(Context context, List<User> data) {
        this.mContext = context;
        this.users = data;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
        ItemUserBinding binding = DataBindingUtil.inflate(inflater, R.layout.item_user, viewGroup, false);
        return new MyViewHolder(binding);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        User user = users.get(position);
        holder.binding.setUser(user);        
    }

    @Override
    public int getItemCount() {
        return users.size();
    }

    //Binding类ViewHolder
    class MyViewHolder extends RecyclerView.ViewHolder {
        ItemUserBinding binding;

        public MyViewHolder(ItemUserBinding binding) {
            super(binding.getRoot());
            this.binding = binding;
        }
    }
}

//Activity
ActivityMainRecyclerViewBinding recyclerViewBinding = DataBindingUtil.setContentView(this, R.layout.activity_main_recycler_view);
List<User> users = new ArrayList<>();
users.add(new User("hongtao", "123456"));
users.add(new User("jiangyan", "654321"));
users.add(new User("xiaohui", "111111"));
MainAdapter mAdapter = new MainAdapter(MainActivity.this, users);
//将Adapter与DataBinding中定义的adapter绑定
recyclerViewBinding.setAdapter(mAdapter);

参考资料

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android DataBinding布局的加载深入探究 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • 源码分析Java中ThreadPoolExecutor的底层原理

    源码分析Java中ThreadPoolExecutor的底层原理 1. 简介 ThreadPoolExecutor是Java提供的一个线程池的实现类,利用它可以实现线程池的管理、控制和优化。该类实现了ExecutorService和AbstractExecutorService接口,是实现线程池的关键。 本篇文章将对ThreadPoolExecutor进行源…

    other 2023年6月27日
    00
  • 屏蔽网页右键复制和ctrl+c复制的js代码

    要屏蔽网页右键复制和Ctrl+C复制功能,可以使用JavaScript编写代码。以下是具体的攻略步骤: 使用addEventListener()方法捕捉右键点击事件。 使用event.preventDefault()方法阻止捕捉到的事件的默认动作,即阻止右键菜单的弹出。 使用document.onkeydown()方法捕捉键盘按下事件。 检测是否同时按下了C…

    other 2023年6月27日
    00
  • mysql中设置默认时间为系统当前时间

    以下是“MySQL中设置默认时间为系统当前时间的完整攻略”,过程中包含两个示例说明的标准Markdown格式文本: MySQL中设置默认时间为系统当前时间 在MySQL中,可以设置默认时间为系统当前时间。以下是设置默认时间的详细步骤: 创建表时设置默认时间。可以在创建表设置默认时间。例如,以下是创建表时设置默认时间的示例: mysql CREATE TABL…

    other 2023年5月10日
    00
  • Cookie的工作原理和应用详解

    Cookie的工作原理和应用详解 什么是Cookie Cookie,中文名称为“饼干”,指的是服务器存储在用户浏览器上的一小段文本信息。Cookie是HTTP协议用于保存状态信息的一种机制,主要是为了记录用户在站点内的一些个性化信息和操作历史,并通过该信息,向访问同一站点的其他页面提供服务。 Cookie如何工作 当Web浏览器访问一个页面时,页面中可能要求…

    other 2023年6月26日
    00
  • JS中的作用域链

    JS中的作用域链 作用域链是JavaScript中一个重要的概念,它决定了变量和函数的可访问性。在理解作用域链之前,我们需要先了解作用域和词法环境的概念。 作用域 作用域是指变量和函数的可访问范围。在JavaScript中,有全局作用域和局部作用域两种。 全局作用域:全局作用域是指在整个JavaScript程序中都可以访问的变量和函数。它在程序开始执行时创建…

    other 2023年8月19日
    00
  • iOS9.0.2固件下载 iOS9.0.2官方固件下载地址大全

    iOS9.0.2固件下载攻略 1. 确定设备兼容性 首先,您需要确保您的设备兼容iOS 9.0.2固件。iOS 9.0.2支持以下设备:- iPhone 6s Plus、iPhone 6s、iPhone 6 Plus、iPhone 6、iPhone 5s、iPhone 5c、iPhone 5、iPhone 4s- iPad Pro、iPad Air 2、iP…

    other 2023年8月4日
    00
  • 云原生要素配置分离ConfigMap创建方式

    下面是“云原生要素配置分离ConfigMap创建方式”的完整攻略: 什么是云原生要素配置分离? 在云原生架构中,配置管理是非常关键的一项工作。云原生要素配置分离指的是,将配置与应用程序本身分离,存储到 ConfigMap 中,将应用程序与其配置解耦。这样做的好处是,可以很方便地对应用程序进行升级、回滚或者替换,而无需重新配置应用。 创建 ConfigMap …

    other 2023年6月25日
    00
  • jQuery实现页面滚动时动态加载内容的方法

    当页面随着滚动动作不断上下移动时,我们往往希望页面可以动态地加载内容,实现更加流畅的用户体验。在这种情况下,jQuery是一个非常有用的工具,它可以轻松地实现这一任务。下面是一些详细介绍: 1. 理解jQuery的滚动事件和AJAX 首先,需要对jQuery的滚动事件有一定的了解,以及如何利用AJAX从后端获取数据。一旦我们掌握了这两个方面的知识,就可以开始…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部