美文网首页
Jetpack之Databinding

Jetpack之Databinding

作者: 放羊娃华振 | 来源:发表于2022-09-19 10:56 被阅读0次

一、概述

数据绑定库是一种支持库,借助该库,您可以使用声明性格式(而非程序化地)将布局中的界面组件绑定到应用中的数据源。
在不适用Databinding的时的代码实现:

    TextView textView = findViewById(R.id.sample_text);
    textView.setText(viewModel.getUserName());

再看一个使用databinding的代码实现:

    <TextView
       android:text="@{viewmodel.userName}" />

借助布局文件中的绑定组件,您可以移除 Activity 中的许多界面框架调用,使其维护起来更简单、方便。还可以提高应用性能,并且有助于防止内存泄漏以及避免发生 Null 指针异常。

二、使用

1. Activity中的变化参考
class ObservableFieldActivity : AppCompatActivity() {

    private val observableFieldProfile = ObservableFieldProfile("Ada", "Lovelace", ObservableInt(0))

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val binding: ObservableFieldProfileBinding =
                DataBindingUtil.setContentView(this, R.layout.observable_field_profile)
        binding.user = observableFieldProfile
    }

    /**
     * This method is triggered by the `android:onclick` attribute in the layout. It puts business
     * logic in the activity, which is not ideal. See {@link ViewModelActivity} for a better
     * solution.
     */
    fun onLike(view: View) {
        observableFieldProfile.likes.set(observableFieldProfile.likes.get() + 1)
    }
}

这个和普通Activity的setContentView()方法不一样了,需要使用DataBindingUtil.setContentView()方法。

2.xml文件的变化参考
<?xml version="1.0" encoding="utf-8"?>
<!--
  Copyright (C) 2018 The Android Open Source Project
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
       http://www.apache.org/licenses/LICENSE-2.0
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  -->

<!-- This layout contains some patterns that should be avoided and are fixed in
 the viewmodel layout. -->
<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>

        <import type="com.example.android.databinding.basicsample.R"/>
        <import type="com.example.android.databinding.basicsample.util.ConverterUtil"/>
        <variable
            name="user"
            type="com.example.android.databinding.basicsample.data.ObservableFieldProfile" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="128dp"
            android:layout_marginStart="16dp"
            android:layout_marginTop="8dp"
            android:text="@{user.name}"
            android:textAppearance="@style/TextAppearance.AppCompat.Large"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/name_label"/>

        <TextView
            android:id="@+id/lastname"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="128dp"
            android:layout_marginStart="16dp"
            android:layout_marginTop="8dp"
            android:text="@{user.lastName}"
            android:textAppearance="@style/TextAppearance.AppCompat.Large"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/lastname_label"/>
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Xml文件的主要变化如下:

  • 布局外层加了layout标签
  • layout标签里面加了data标签
  • 布局中赋值的地方使用了表达是@{xxx.xxx}
3.表达式语言

表达式语言与托管代码中的表达式非常相似。您可以在表达式语言中使用以下运算符和关键字:

  • 算术运算符 + - / * %
  • 字符串连接运算符 +
  • 逻辑运算符 && ||
  • 二元运算符 & | ^
  • 一元运算符 + - ! ~
  • 移位运算符 >> >>> <<
  • 比较运算符 == > < >= <=(请注意,< 需要转义为 <)
  • instanceof
  • 分组运算符 ()
  • 字面量运算符 - 字符、字符串、数字、null
  • 类型转换
  • 方法调用
  • 字段访问
  • 数组访问 []
  • 三元运算符 ?:
  • Null 合并运算符:??

其余的布局和表达式相关可以参考文档

4.双向绑定参考文档

使用单向数据绑定时,您可以为特性设置值,并设置对该特性的变化作出反应的监听器:

<CheckBox
        android:id="@+id/rememberMeCheckBox"
        android:checked="@{viewmodel.rememberMe}"
        android:onCheckedChanged="@{viewmodel.rememberMeChanged}"
    />

双向数据绑定为此过程提供了一种快捷方式:

<CheckBox
        android:id="@+id/rememberMeCheckBox"
        android:checked="@={viewmodel.rememberMe}"
    />

@={} 表示法(其中重要的是包含“=”符号)可接收属性的数据更改并同时监听用户更新。

为了对后台数据的变化作出反应,您可以将您的布局变量设置为 Observable(通常为 BaseObservable)的实现,并使用 @Bindable 注释,如以下代码段所示:

public class LoginViewModel extends BaseObservable {
        // private Model data = ...

        @Bindable
        public Boolean getRememberMe() {
            return data.rememberMe;
        }

        public void setRememberMe(Boolean value) {
            // Avoids infinite loops.
            if (data.rememberMe != value) {
                data.rememberMe = value;

                // React to the change.
                saveData();

                // Notify observers of a new value.
                notifyPropertyChanged(BR.remember_me);
            }
        }
    }

由于可绑定属性的 getter 方法称为 getRememberMe(),因此属性的相应 setter 方法会自动使用名称 setRememberMe()

有关 BaseObservable@Bindable 用法的详细信息,请参阅使用可观察的数据对象

相关文章

网友评论

      本文标题:Jetpack之Databinding

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