问题
I have 2 Group
s 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