首页 > 解决方案 > android MVVM架构中Layout Binding和Manual Binding(with observe)的比较

问题描述

使用 Android Jetpack 组件和 MVVM 架构,我们可以通过两种方式从 View Model 中获取 View 中的实时数据更新,一种是将布局与实时数据变量绑定,另一种是在代码中观察变量。为了说明我的问题,我举了一个例子。假设有一个视图模型接口 getTimeString() 返回当前时间。

a)布局数据绑定

  1. 布局中的视图看起来像这样

        <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        ... 
        app:binder_data_date="@{sampleVM.timeString}"/>
    
  2. 绑定适配器看起来像这样

    @BindingAdapter("binder_data_date")
    public static void binder_data_date(TextView text, String data) {
        text.setText(data);
    }
    

b)手动数据绑定(只是给它一个名字):在手动数据绑定中,布局视图中没有任何关于活页夹的内容,我使用observe()观察实时数据并更新文本视图。

 FragmentSplashScreenManualBindingBinding fragmentSplashScreenBinding;
SampleViewModel sampleViewModel1 = ViewModelProviders.of(this).get(SampleViewModel.class);

public void onSomeRandomFunc(...) {
 .... 
 sampleViewModel1.getTimeString().observe(getViewLifecycleOwner(), data -> {
        fragmentSplashScreenBinding.sampleText.setText(data);
    });
 }

我知道第一种方法更容易使用,而且两种方法都有效。

  1. 但是使用第二种方法和访问片段中的变量(fragmentSplashScreenBinding.sampleText.setText())的方式来更新视图是否正确?
  2. 如果我使用第二种方法,性能会受到影响吗?

标签: androidandroid-layoutandroid-fragmentsandroid-jetpackandroid-mvvm

解决方案


而不是直接在帖子中回答你的 2 点——让我提一下数据绑定和实时数据的几个关键特性——这最终可能会帮助你选择 1 而不是另一个。

实时数据类支持转换- 这个有用的类提供了一种在将实时数据对象分派给观察者之前应用对实时数据对象进行的任何更改的方法,或者您可能需要LiveData根据另一个实例的值返回不同的实例。LiveData下面是从官方 android 文档应用转换的示例,

类 ScheduleViewModel : ViewModel() { val userName: LiveData

init {
    val result = Repository.userName
    userName = Transformations.map(result) { result -> result.value }
} }

正如您从上面的示例中看到的 - 在“ init”中,LiveData对象Transformations.map在将其内容分派给“观察者”之前使用“转换”

数据绑定主要与一组 Observable 一起使用,并且不能像上面的示例那样在调度之前“转换”观察下的数据。

with 的另一个有用的特性LiveData是一个名为的类MediatorLiveData——这个子类可以观察其他LiveData对象并根据对它的更改做出反应——通过数据绑定 AFAIK,它非常受限于特定的可观察字段。


推荐阅读