美文网首页
[学习]JetPack中的DataBinding(一)

[学习]JetPack中的DataBinding(一)

作者: 吴敬悦 | 来源:发表于2021-02-03 14:56 被阅读0次

以后我都会使用 kotlin 来实现。第一篇是简单使用。

1. 准备工作

打开文件 app > build.gradle 文件,添加代码如下:

...
// 这是为了 kotlin 的支持
apply plugin: 'kotlin-kapt'
...
android {
  ...
  // 添加下面的代码
  dataBinging {
    enabled: true
  }
  ...
}

2. 准备简单的布局文件

打开 activity_main.xml 文件,如下:

<?xml version="1.0" encoding="utf-8"?>
<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="number"
        type="androidx.databinding.ObservableInt" />
  </data>
  <androidx.constraintlayout.widget.ConstraintLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{Integer.toString(number)}"
        android:textSize="32sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.397" />

    <Button
        android:id="@+id/sub"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="32dp"
        android:layout_marginTop="16dp"
        android:text="@string/sub"
        app:layout_constraintBottom_toBottomOf="@+id/add"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <Button
        android:id="@+id/add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="32dp"
        android:text="@string/add"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

  </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

主要做的工作就是将布局换成 layout 打头,原有的布局不变,之所以这样是为了给 data 标签提供空间,这个应该是 layout 这个布局中解析的,原理我不懂,现在主要是使用。布局的效果如下:

要实现的效果布局

3. demo说明

要提供的功能很简单,只需要点击增加所对应的数字 +1 ,点击减少所对应的数字 -1

要是在以前需要在点击的时候改变 TextViewtext 属性的值,所以首先需要获取 TextView ,然后才能进行相关操作,所以如果界面需要修改的多的话就会出现很多获得实例的代码,有了 DataBinding 就简单多了。

4. DataBinding

如果需要改变则需要使用官网提供的类型,不能使用编程语言里面提供的类型。相关类型
需要添加的变量放在 xml 文件中的 data 标签下:

<data>
    <!-- variable 就是放对应属性 -->
    <variable
        name="number"
        type="androidx.databinding.ObservableInt" />
  </data>

基本类型都有对应的:

Int ObservableInt
Boolean ObservableBoolean
...

如果是引用类型,那就使用 ObservableField

val name: ObjservableFild<String> = "吴敬悦";

不要看我使用的是 val ,但是没有关系,这个是一个类,修改值的时候需要使用类里面提供的方法,而不是直接开干,这让我想到了 vue 的数据双向绑定;学的东西都是通用的,特别是越底层的越相似。这里使用的就是观察者模式嘛,源码我不知道,但我发现可以使用其思路理解和分析。

通过上面的操作,插件就会自动帮我们生成一个类 ActivityMainBinding ,当然这里又规则的,不是随便生成的名称,只不过影响不大,只要输入当前的 ActivityFragment 名称就会出现,最后都是以 Binding 结尾。

绑定布局文件,这里要用到 DataBindingUtil 类:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // 绑定数据和布局
    binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    // 初始化数据
    binding.number = number
}

这里的 binding 里面的属性包含 xml 布局文件中的所有 data 标签下的属性,我这里只有 number ,所以我就初始化这一个。同时 binding 下还有根据 id 生成的属性,也就说我们即便不使用绑定,这个也能简化我们获取对应的节点的代码。

接下来看看点击的两个事件:

fun onAdd(view: View) {
    number.set(number.get() + 1)
}
fun onSub(view: View) {
    number.set(number.get() - 1)
}

其中 setget 都是对应 ObservableInt 类提供的对象,下面是完整的代码 MainActivity.kt

class MainActivity : AppCompatActivity() {
    private val number = ObservableInt(10)
    private lateinit var binding: ActivityMainBinding;
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.number = number
    }
    fun onAdd(view: View) {
        number.set(number.get() + 1)
    }
    fun onSub(view: View) {
        number.set(number.get() - 1)
    }
}

这样简单的功能就实现了,感觉很舒坦,再也不像以前那样了,同时跟前端很相似了。而且我觉得这种比 reactvue 好一点的是,界面和逻辑分离,在写 react 的时候逻辑和 UI 很容易写出混乱不堪的代码。当然了,这样就没有了前端的灵活了。

相关文章

网友评论

      本文标题:[学习]JetPack中的DataBinding(一)

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