soapgu / PlayPen

学习笔记

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Android 练手之旅——DataBinding简介

soapgu opened this issue · comments

前言

DataBinding是一个非常非常重要的功能,它是实现MVVM架构的关键技术。
拥有了DataBinding才真正做到了UI和数据逻辑解耦。
这里跟着教程一步步学是最好的
android-databinding
中文版教程

环境准备

在模块级的build.gradle里面加入

android {
        dataBinding {
            enabled = true
        }
    }

这里有坑,

  1. 首先dataBinding 这个标记都不认
    项目级里面的gradle版本需要升级到最新(原版3.4是不支持的)
    classpath 'com.android.tools.build:gradle:4.1.2'

2.gradle工具版本也要升级到新版
gradle-wrapper.properties里面的distributionUrl

layout修改

  1. 到UI根元素下利用IDE改成binding模式
    select Show Context Actions, then Convert to data binding layout

2.在data增加绑定值

    <data>
       <variable
           name="viewmodel"
           type="com.example.android.databinding.basicsample.data.SimpleViewModel"/>
   </data>

3 在相关View元素中增加绑定表达式

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

和WPF没有太多区别,支持.下去嵌套

4 绑定方法

<Button
            android:id="@+id/like_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            android:onClick="@{()->viewmodel.onLike()}"
            android:text="@string/like"
            app:layout_constraintBottom_toTopOf="@+id/progressBar"
            app:layout_constraintEnd_toEndOf="@+id/imageView"
            app:layout_constraintStart_toStartOf="@+id/imageView"
            app:layout_constraintTop_toBottomOf="@+id/likes" />

绑定方法还要直观易懂,感觉比WPF的绑定方法做得还要好

  1. 布局文件Binding类,这是我们的DataBinding组件帮我们自动完成的,虽然不需要额外的工作但是蛮重要,需要说明下
    系统会为每个布局文件生成一个绑定类。默认情况下,类名称基于布局文件的名称,它会转换为 Pascal 大小写形式并在末尾添加 Binding 后缀,就是 {layoutname}Binding。
    图片
    有兴趣的可以转到java(genrerate)

Activity部分绑定值传入

val binding : PlainActivityBinding =
                DataBindingUtil.setContentView(this, R.layout.plain_activity)
        
        binding.lifecycleOwner = this
        binding.viewmodel = viewModel

这部分代码属于KT,语法上没有啥障碍
这里数据对象就是viewmodel ,binding.viewmodel和前面布局xml文件里面data定义的变量一致。ViewModel又是一个走上MVVM之路的重要杀器,这里暂且不表

绑定数据类型定义及更新通知

这里数据的更新通知到UI有几种方式实现
1 继承BaseObservable ,Get增加@bindable标记Set 调用notifyPropertyChanged(BR.{prop})。
看到代码学过WPF的同学心领神会。

private static class User extends BaseObservable {
        private String firstName;
        private String lastName;

        @Bindable
        public String getFirstName() {
            return this.firstName;
        }

        @Bindable
        public String getLastName() {
            return this.lastName;
        }

        public void setFirstName(String firstName) {
            this.firstName = firstName;
            notifyPropertyChanged(BR.firstName);
        }

        public void setLastName(String lastName) {
            this.lastName = lastName;
            notifyPropertyChanged(BR.lastName);
        }
    }

在编译期间,Bindable 注释会在 BR 类文件中生成一个条目
2 LiveData组件

private val _name = MutableLiveData("Ada")
    private val _lastName = MutableLiveData("Lovelace")
    private val _likes =  MutableLiveData(0)

    val name: LiveData<String> = _name
    val lastName: LiveData<String> = _lastName
    val likes: LiveData<Int> = _likes

3 ObservableField

绑定适配器

展开篇幅很大,这里概况下。学过WPF的同学 可以理解为Attached DependencyProperty( 附加依赖属性 )
所以这里的方法是静态的

@BindingAdapter("android:paddingLeft")
    public static void setPaddingLeft(View view, int oldPadding, int newPadding) {
    ...
}

关键点
1 BindingAdapter标记
2 标记参数,android:paddingLeft,可以在layout中声明相关(附加)属性
3 View,这里可以更具体类的对象,比如ImageView
4 target value
这里是最典型用法,还有很多扩展,也可以是事件监听器对象。满足各种需要,总有一款适合你

Convesion

简述下,学过WPF的同学可以和Converter对标

@BindingConversion
public static ColorDrawable convertColorToDrawable(int color) {
    return new ColorDrawable(color);
}

大家可以体会下代码。
这里和WPF不同之处在于无需在layout的xml显示定义。作用域待考察,似乎是模块内的

总结下,Android的DataBinding非常的优雅。学过WPF的同学应该是无障碍理解。