Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android 练手之旅——DataBinding简介 #6

Open
soapgu opened this issue Mar 2, 2021 · 0 comments
Open

Android 练手之旅——DataBinding简介 #6

soapgu opened this issue Mar 2, 2021 · 0 comments
Labels
mvvm This issue or pull request already exists 安卓 安卓

Comments

@soapgu
Copy link
Owner

soapgu commented Mar 2, 2021

前言

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的同学应该是无障碍理解。

@soapgu soapgu added the 安卓 安卓 label Mar 2, 2021
@soapgu soapgu added the mvvm This issue or pull request already exists label Jun 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mvvm This issue or pull request already exists 安卓 安卓
Projects
None yet
Development

No branches or pull requests

1 participant