【问题标题】:2 way Databinding with ViewModel-SavedState2 路数据绑定与 ViewModel-SavedState
【发布时间】:2020-03-27 05:14:43
【问题描述】:

我有一个订阅表单:姓名、地址、本地等等……我希望能够使用Data BindingLiveDataSavedStateHandle 来处理和保存数据。

假设:1 路 Data BindingLiveDataSavedStateHandle

private val _name: MutableLiveData<Boolean> = stateHandle.getLiveData("_name", "")
val name: LiveData<String> = _name

fun onNameChanged(editable: Editable) {
    _name.value = editable.toString()
}

<EditText
    android:text="@{viewModel.name}"
    android:afterTextChanged="@{viewModel::onNameChanged}"
    ...
/>

这可行,但我认为我们可以做得更好:

  • @Parcelize class Form 封装所有字段
  • 2-way Data Binding减少.xml代码

现在问题开始出现了。
如何通知我Form class 内部的更改,以便能够将objectSavedState 保持一致?尝试改进上面的代码或使用2-way Data Binding 我们失去控制实际上有优势吗?我还使用一些逻辑来启用这样的提交按钮:

private val _name: MutableLiveData<String> = stateHandle.getLiveData("_name", "")   
val name = _name.map { value -> {
    updateUi()
    return value}
}

private val _formValidLiveData = MutableLiveData<Unit>()
val submitEnable = _formValidLiveData.map { _ -> isFormValid() }
val submitAlpha = _formValidLiveData.map { _ -> if (isFormValid()) 1f else 0.5f }
...
private fun updateUi() {
    _formValidLiveData.value = Unit
}

同样,2-way Data Binding 我失去了控制,当EditText 字段更改时,我如何调用updateUi()
感谢您的宝贵时间。

【问题讨论】:

  • 如果你想使用双向绑定,为什么不使用public val name: MutableLiveData&lt;Boolean&gt;
  • @EpicPandaForce,实际上这是一个好点,我完全错过了。但是现在我怎样才能对那个 MutableLiveData 应用一个转换呢?因为我想为 UX 目的执行 updateUi(),所以每次字段更改时。问题 2:我怎样才能拥有一个能够使用 SavedState 存储的数据类(或类),并且它的字段是双向绑定的?
  • 啊,这很棘手,您可以定义一个私有 MediatorLiveData 来触发始终观察此 MutableLiveData 的内部更改。
  • 你为什么不直接stateHandle.set(KEY, VALUE) 而不必关心MutableLiveData

标签: android android-databinding android-architecture-components 2-way-object-databinding viewmodel-savedstate


【解决方案1】:

好的,遇到了类似的问题 - 并对此进行了测试,似乎工作正常:

public class LoginViewModel extends AndroidViewModel {

  public final MutableLiveData<String> mUsername;
  private SavedStateHandle handle;

  public LoginViewModel(Application application, SavedStateHandle handle) {
    // If this is the first time entering the activity, mUsername will be created, populated by value 'BLAH' and stored in the handler.
    // else, this will will be the last set value
    mUsername = handle.getLiveData("mUsername", "BLAH");
  }
}

现在,我在 2-way 绑定用户名字段中输入了一些值,在 xml 中定义如下:

<com.google.android.material.textfield.TextInputLayout
     android:id="@+id/username_wrapper"
     android:layout_below="@id/header_container"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_marginBottom="@dimen/general_padding"
     android:theme="@style/TextInputLayoutAppearance"
     android:hint="@string/username">
       <com.google.android.material.textfield.TextInputEditText
          android:id="@+id/username_field"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:inputType="textEmailAddress"
           android:text="@={ viewModel.mUsername }"/>
      </com.google.android.material.textfield.TextInputLayout>

为了测试,我在字段中输入了一些数据,然后按照下面链接的答案进行操作。该字段每次都设置为最新输入的值。为了确保这一点,我还在视图模型的构造函数中放置了一个断点 - 您可以看到该值已正确填充!因此,似乎有两种数据绑定方式可以正常工作。

导航离开时触发活动/视图模型销毁的链接:Android viewModel savedStateHandle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 2017-11-05
    • 1970-01-01
    • 2017-12-16
    相关资源
    最近更新 更多