【问题标题】:How can I set a ConstraintLayout Group's visibility via DataBinding?如何通过 DataBinding 设置 ConstraintLayout Group 的可见性?
【发布时间】:2021-01-21 11:49:59
【问题描述】:

我的布局中有 2 个Groups,用于控制我的视图的可见性。
但是,我无法通过 DataBinding 设置它们的可见性:

<layout>
    <data>
        <import type="android.view.View"/>
        
        <variable
            name="viewModel"
            type="co.aresid.book13.fragments.trackinglist.TrackingListViewModel"
            />
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout>

        ...

        <androidx.constraintlayout.widget.Group
            android:id="@+id/content_group"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:visibility="@{viewModel.hideLoadingAndShowContent ? View.VISIBLE : View.GONE, default=gone}"
            app:constraint_referenced_ids="tracking_list_recycler_view"
            />
        
        <androidx.constraintlayout.widget.Group
            android:id="@+id/loading_group"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:visibility="@{viewModel.hideLoadingAndShowContent ? View.GONE : View.VISIBLE, default=visible}"
            app:constraint_referenced_ids="progress_circular"
            />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

hideLoadingAndShowContent 变量是一个LiveData,它的值来自我的ViewModel 中对应的MutableLiveData

private val _hideLoadingAndShowContent = MutableLiveData<Boolean>()
val hideLoadingAndShowContent: LiveData<Boolean>
    get() = _hideLoadingAndShowContent

这个LiveData 只设置在ViewModel 中,不会出现在Fragment 类中。
Fragment类中,我也设置了binding.lifecycleOwner

binding.lifecycleOwner = viewLifecycleOwner

我遗漏了哪些细节?

【问题讨论】:

  • 能否将代码 kotlin sn-p where inflate view 和 setviewmodel 添加到绑定

标签: android android-livedata android-databinding


【解决方案1】:

我忘记将ViewModel 传递给我的Fragment 类中的布局绑定:

binding.viewModel = viewModel

【讨论】:

    【解决方案2】:

    因为android:visibility不支持绑定变量观察,

    您可以通过这种方式创建 BindingAdapter

    @BindingAdapter("mutableVisibility")
    fun setMutableVisibility(view: View, visibility: MutableLiveData<Boolean>) {
        val owner = (view.getParentActivity() ?: view.context) as LifecycleOwner
        if (owner != null) {
            visibility.observe(
                owner,
                Observer { value ->
                      view.visibility = if(value) View.VISIBLE else View.GONE
                })
        }
    }
    

    从视图中获取活动的实用功能。

    fun View.getParentActivity(): AppCompatActivity?{
        var context = this.context
        while (context is ContextWrapper) {
            if (context is AppCompatActivity) {
                return context
            }
            context = context.baseContext
        }
        return null
    }
    

    然后在你的 XML 中你可以这样做

     <androidx.constraintlayout.widget.Group
                android:id="@+id/content_group"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:visibility="@{viewModel.hideLoadingAndShowContent}"
                app:constraint_referenced_ids="tracking_list_recycler_view"
                />
    

    【讨论】:

    • 感谢您的回答。然而,这似乎不是真的:developer.android.com/topic/libraries/data-binding/…。我还阅读了另一个 SO 问题,它按照我的方式工作。
    • 嗯,回答需要一些努力,甚至没有测试就投票否决答案会阻止回答者
    • @RenéSpies 你说的是真的,但它一次有效,当你将字段或模型与 viewdatabinding 对象绑定时发生绑定,然后它不会,所以对于值会改变的实时数据在运行时,您可以使用 Bindingadapter 来做到这一点。
    • @RenéSpies 我知道,但是有人这样做了。
    • 能分享一下你绑定viewmodel的代码吗
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 2021-08-18
    • 1970-01-01
    • 2019-06-19
    • 1970-01-01
    • 2014-02-24
    • 2010-10-25
    相关资源
    最近更新 更多