使用LiveData设置TextView的可见性

12

我想使用LiveData来切换TextView的可见性。已经有一些其他帖子介绍了如何使用数据绑定设置可见性,但这些帖子都使用Observables,而我想利用(更新的)LiveData。特别地,使用一个LiveData。

根据这份文档和一些SO帖子,我已经学到了正确对齐可观察对象(LiveData)的getter方法,使其返回类型与要设置的视图属性的setter方法所期望的类型相匹配。具体地:

  • View的setVisibility()需要一个int类型,而我有一个LiveData成员变量(因此我的ViewModel中的getter方法也将返回此类型)
  • 使用三元运算符将该布尔值转换为View.VISIBLE和VIEW.GONE是可能的,我还应该在我的XML表达式中添加safeUnbox()来使它成为原始布尔值

利用这些见解,在我的ViewModel类中,我定义了:

MutableLiveData<Boolean> textHintVisible;
在按下按钮后,我将此值设置为False:
textHintVisible.postValue(false);

(注:我也尝试使用setValue()方法。)

然后,在我的布局XML中,我已经包含了:

<TextView
   android:visibility="@{(safeUnbox(viewModel.textHintVisible) ? View.VISIBLE : View.GONE)}"
/>

但是,我的TextView仍然始终可见。为了调试,我在我的活动中添加了一个观察者,这证实了我的布尔值在true和false之间正确切换:

mHintsViewModel.getTextHintVisible().observe(this, new Observer<Boolean>() {
   @Override
   public void onChanged(@Nullable Boolean newInt) {
        Log.i(TAG,"onChanged: "+newInt);
   }
});

但是我的TextView一直可见。我做错了什么?使用LiveData不可能实现这个吗?我应该使用额外的转换器吗?还是我的代码原则上正确,但这是Android Studio的一个错误?非常感谢任何帮助。


1
我心里想到的一件事是 - 你是否已将绑定设置为观察LiveData?根据文档https://developer.android.com/topic/libraries/data-binding/architecture,你必须将绑定布局设置为观察生命周期`binding.setLifecycleOwner(this)`。 - mlykotom
这确实是问题所在!非常感谢! - user3820186
我把它发布为答案,这样您可以接受它,其他人也可以看到它已解决并找到答案,而不仅仅是在评论中:) - mlykotom
与此LiveData变量相关的所有代码都将非常有用。您提到“因此,我的ViewModel中的getter也将返回此类型”,但是“使用三元运算符将此布尔值转换为View.VISIBLE和VIEW.GONE是可能的”告诉我getter可以返回布尔值,但是三元运算符将在原地将其转换为int,但它似乎没有按照描述的那样工作。实际上,我们只是缺少getTextHintVisible()方法。 - DevinM
1个回答

25

我想说的一件事是 - 你是否设置了绑定以观察LiveData? 根据文档,您必须将绑定布局设置为观察生命周期binding.setLifecycleOwner(this)


5
对于碎片,请使用binding.setLifecycleOwner(viewLifecycleOwner) - Francis
@Francis 为什么我们要将片段的活动作为生命周期所有者?这不是整个过程的重点吗,即将UI附加到片段的生命周期而不是持有它的活动?请提供解释您评论的文档。 - Shadow
2
在Fragment中,您不使用Activity,实际上有两个LifecycleOwners - 1)Fragment本身,2)Fragment的视图。由于片段实例在方向更改后并未被销毁,只有其视图被销毁,因此需要将绑定的生命周期设置为视图的生命周期,否则可能会发生内存泄漏。 - mlykotom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接