How can I set a ConstraintLayout Group's visibility via DataBinding?

懵懂的女人 提交于 2021-01-29 10:49:43

问题


I have 2 Groups in my layout which control the visibility of my Views.
However, I cannot set their visibility via 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>

The hideLoadingAndShowContent variable is a LiveData which gets its value from a corresponding MutableLiveData in my ViewModel:

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

This LiveData is only set in the ViewModel and does not occur in the Fragment class.
In the Fragment class, I have also set the binding.lifecycleOwner:

binding.lifecycleOwner = viewLifecycleOwner

What detail am I missing out?


回答1:


I forgot to pass the ViewModel to the layout binding in my Fragment class:

binding.viewModel = viewModel



回答2:


Because that android:visibility does not support binding variable observation,

You can create BindingAdapter this way

@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
            })
    }
}

Utility function for getting activity from view.

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

Then in your XML you can do it like

 <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"
            />


来源:https://stackoverflow.com/questions/65826800/how-can-i-set-a-constraintlayout-groups-visibility-via-databinding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!