[Module] 06 - DataBinding and MVVM

时间:2023-02-08 13:22:08

下一步学习列表:

Android DataBinding使用总结(一) ***

Android DataBinding使用总结(二)

Android DataBinding使用总结(三)列表展示

Android DataBinding使用总结(四)多类型列表展示

Android DataBinding使用总结(五)结合MultiType展示多类型列表

Android MVVM+DataBinding结合Dagger2进行开发

Android 神兵利器Dagger2使用详解(一)基础使用

Android 神兵利器Dagger2使用详解(二)Module&Component源码分析

Android 神兵利器Dagger2使用详解(三)MVP架构下的使用

Android 神兵利器Dagger2使用详解(四)Scope注解的使用及源码分析

Android单元测试:Mockito使用详解

Android单元测试:使用本地数据测试Retrofit

Android单元测试:测试RxJava的同步及异步操作

前言

Ref: 如何构建Android MVVM应用程序

Databinding 是一种框架,MVVM是一种模式,两者的概念是不一样的。
DataBinding是一个实现数据和UI绑定的框架,只是一个实现MVVM模式的工具。

相关配置

以前我们在Activity里写很多的findViewById,现在如果我们使用DataBinding,就可以抛弃findViewById。DataBinding主要解决了两个问题:

- 需要多次使用findViewById,损害了应用性能且令人厌烦 
- 更新UI数据需切换至UI线程,将数据分解映射到各个view比较麻烦

Moudle的build.gradle中添加如下代码进行配置:

android {
....
dataBinding {
enabled = true
}
}

绑定示范

代码:https://github.com/qingmei2/MvvmApp-Android

public class A01MainActivity extends AppCompatActivity {

    public  Presenter           presenter;
private ActivityMainBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
inject();  // ---->
} private void inject() {
//现在我们通过DataBindingUtil设置布局文件
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

/**
* 以下看上去像是套路coding
*/
//初始化Presenter对象
presenter = new Presenter();
//将presenter对象赋予XML中的 data -> variable -> presenter
binding.setPresenter(presenter);
} public class Presenter { public String message = " ~ "; public void baseDataBinding() {
startActivity(new Intent(A01MainActivity.this, A02DataBindingBaseActivity.class));
} public void recyclerView(){
startActivity(new Intent(A01MainActivity.this, A03RecyclerBindActivity.class));
} public void mulTypeRecyclerView(){
startActivity(new Intent(A01MainActivity.this, A04MulTypeRecyclerBindActivity.class));
} public void mvvm(){
startActivity(new Intent(A01MainActivity.this, A06MvvmActivity.class));
} public void studyLibrary(){
startActivity(new Intent(A01MainActivity.this, A05MultiTypeStudyActivity.class));
}
}
}

在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="presenter"
type="com.mei_husky.samplemvvm.view.activity.A01MainActivity.Presenter" />
</data> <LinearLayout
android:layout_width ="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.mei_husky.samplemvvm.view.activity.A01MainActivity"> <Button
android:layout_width ="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:onClick="@{() -> presenter.baseDataBinding()}"
android:text="@{`DataBinding基础使用` + presenter.message}" /> <Button
android:layout_width ="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:onClick="@{() -> presenter.recyclerView()}"
android:text="@{`DataBinding 展示列表` + presenter.message}" /> <Button
android:layout_width ="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:onClick="@{() -> presenter.mulTypeRecyclerView()}"
android:text="@{`DataBinding 展示多类型列表` + presenter.message}" /> <Button
android:layout_width ="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:onClick="@{() -> presenter.studyLibrary()}"
android:text="@{`MultiType库学习` + presenter.message}" />
<Button
android:layout_width ="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:onClick="@{() -> presenter.mvvm()}"
android:text="@{`DataBinding Mvvm` + presenter.message}" /> </LinearLayout>
</layout>

以上是基本了解,frankly, it is confused.

所以,我需要视频:棉花糖给 Android 带来的 Data Bindings(数据绑定库)

方案一:ButterKnife

使用 ButterKnife 这个库,能够摆脱讨厌的 findViewById 而获得组件,它让代码更加简洁易读。通过它可以节省很多额外的代码。

private @Bind(R.id.name)     TextView mName
private @Bind(R.id.lastName) TextView mLastName
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
//mName = (TextView) findViewById(R.id.name);
//mLastName = (TextView) findViewById(R.id.lastName);
  ButterKnife.bind(this);
}
public void updateUI(User user) {
if (user == null) {
mName.setText(null);
mLastName.setText(null);
} else {
mName.setText(user.getName());
mLastName.setText(user.getLastName());
}
}

方案二:holder

使用 Holdr,替你可以处理布局文件,然后为他们创建 View 组件。你通过 Holder,转换 View 的 ID 到组件变量。

private Holdr_ActivityMain holder;
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
holder = new Holdr_ActivityMain(findViewById(content));
}
public void updateUI(User user) {
if (user == null) {
holder.name.setText(null);
holder.lastName.setText(null);
} else {
holder.name.setText(user.getName());
holder.lastName.setText(user.getLastName());
}
}

感觉只是在name, lastname之上wrap了一下而已,未体会到伟大的精神。

当你使用 Data Binding,它很像 Holder 模式,而且你只要做一点点事情,其余的内容 Data Binding 会帮你完成。

方案三:databinding

private ActivityMainBinding mBinding;
protected void onCreate(Bundle savedInstanceState) {
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
} public void updateUI(User user) {
mBinding.setUser(user);
}

id的使用开始变得不重要。

<LinearLayout …>
<TextView android:id="@id/name" />
<TextView android:id="@id/lastName" />
</LinearLayout>

我们能够直接通过 Java 代码找到它们,为什么还需要这些 ID 呢?
所以,进化为如下形式:
<LinearLayout …>
<TextView android:text="@{user.name}"/>
<TextView android:text="@{user.lastName}"/>
</LinearLayout>

看起来更明显。

<layout>
<data>
<variable name="user"
type="com.android.example.User"/>
</data>

<LinearLayout …>
<TextView android:text="@{user.name}"/>
<TextView android:text="@{user.lastName}"/>
<TextView android:text='@{"" + user.age}'/>
</LinearLayout>
</layout>

休息 休息...