【问题标题】:Comparison between Layout Binding and Manual Binding(with observe) in MVVM architecture of androidandroid MVVM 架构中布局绑定和手动绑定(带观察)的比较
【发布时间】:2020-08-14 21:22:51
【问题描述】:

使用 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() 观察实时数据并更新 textview。

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

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

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

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

【问题讨论】:

    标签: android android-layout android-fragments android-jetpack android-mvvm


    【解决方案1】:

    您的手动数据绑定没有错误,不会对性能产生重大影响,但您会失去两个好处:

    1. 空指针异常处理Layout Data Binding 处理空数据,当您要提取数据对象并将其传递给视图时,无需检查空对象以防止应用崩溃。
    2. 代码可重用性:如果你想在不同的Activities 中使用你的布局,使用 Layout Data Binding 你只需要将数据变量传递给布局。但是对于Manual Data binding,您应该为每个 java 类复制相同的代码以将变量分配给视图,这将在复杂视图中产生大量样板代码。

    此外,如果您使用数据绑定来替换 findViewById() 作为您的第二种方法,还有一种更好的方法称为 View Binding,您可以阅读更多关于它的信息 here

    【讨论】:

    • 你确定布局处理空值吗?如果它是从视图模型发送的,我也看到 null 被传递给 binder 函数。你能提供一些相同的android文档参考吗?
    • 另外,你可以自己测试一下
    【解决方案2】:

    与其在帖子中直接回答您的 2 点 - 让我提一下数据绑定和实时数据的一些关键特性 - 这最终可能会帮助您选择 1 点。

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

    类 ScheduleViewModel : ViewModel() { val 用户名:LiveData

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-20
      • 1970-01-01
      • 1970-01-01
      • 2019-06-14
      • 1970-01-01
      • 2017-06-02
      • 2012-11-02
      • 1970-01-01
      相关资源
      最近更新 更多