为向往生活努力奋斗!

使用 Data Binding 的双向绑定巧妙实现 EditText 文本监听

2022.04.07

前言

若项目使用 Data Binding 框架时,实现对 EditText 控件的文本输入监听,主要有三种方法:

  1. 事件绑定
  2. BindingAdapter 注解
  3. 双向绑定

本文主要讲解第三种方法《双向绑定》,当你懂得用起来之后会发现真香。

需求背景

“在输入框右下角实时展示输入内容的长度变化”,界面展示如下图:

这么一个简单需求,下面就说下如何使用 Data Binding 的双向绑定实现。

实现代码

先看下布局 xml 这块的代码

<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>
        <variable
            name="viewModel"
            type="TestViewModel" />
    </data>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/edit_desc"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={viewModel.inputContent}" />

        <TextView
            android:id="@+id/tv_edit_number"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{viewModel.getInputLengthText(viewModel.inputContent.length)}"
            tools:text="0/500" />

    </FrameLayout>
</layout>

上面代码主要留意下布局控件中的 text 属性的赋值

再来看下 ViewModel 里写的代码

class TestViewModel(
	application: Application
) : BaseAndroidViewModel(application) {

	// 定义输入框内容输入的可观察字段
	var inputContent = ObservableField<String>()	

	// 根据输入的长度返回拼接成指定格式字符
	fun getInputLengthText(length: Int) : String = String.format(Locale.US, "%d/500", length)
}

讲解代码

<EditText
    ...
    android:text="@={viewModel.inputContent}"
    ...
    />

重点留意下 @={} 表示法(其中最重要的是包含了 “=” 符号)接收属性的数据更改并同时更新,这就是双向数据绑定提供的一种快捷方式。

<TextView
    ...        
    android:text="@{viewModel.getInputLengthText(viewModel.inputContent.length)}"
    tools:text="0/500"
    ...
    />

这句的代码就比较简单理解了,当 inputContent 可观察字段数据变化会触发到这里重新获取长度字符串进行赋值到 TextView 控件。

总结

大家看完之后,是不是感觉使用 DataBinding 双向绑定来实现这需求简单很多,若使用另外两种方法就会稍微复杂点写的代码也会更多点,个人觉得双向绑定方式适用在比较简单的功能实现上,各位可根据不同需求来选取不同方法实现。

另外官方提供支持双向绑定的属性只是部分的,不是所有控件的属性都可使用。具体支持哪些可看下图:

参考链接