View container visibility based on the visibility of views contained in it

240 Views Asked by At

I have several views inside another view. I need to show the container view if at least one view is visible. So, if none of the view's visibility is VISIBLE, then the container should itself hide.

It could be done by using constraintlayout group or any other ways in fragment.

But I am using Data Binding and I needed to handle it in ViewModel with LiveData. So I tried using MediatorLiveData. And it is not working as expected.

Here is how my code looks like:

class MyViewModel: ViewModel() {
    
    val firstViewVisibility: LiveData<Int> = checkVisibility(firstView)
    val secondViewVisibility: LiveData<Int> = checkVisibility(secondView)
    val thirdViewVisibility: LiveData<Int> = checkVisibility(thirdView)

    // and so on

    val viewContainerVisibility = MediatorLiveData<Int>.apply {
        fun update(visibility: Int) {
            value = visibility
        }

        addSource(firstViewVisibility) {
            update(it)
        }

        addSource(secondViewVisibility) {
            update(it)
        }

        addSource(thirdViewVisibility) {
            update(it)
        }

        // and so on
    }
}

CheckVisibility function:

private fun checkVisibility(viewType: String) =
    Transformations.map(myLiveData) { value ->
        if(some logic involving value returns true) View.VISIBLE 
        else View.GONE
    }

This is not working as the parent view's visibility depends upon the visibility added by last addSource in MediatorLiveData. So, if the last view's visibility is VISIBLE then the parent will be Visible and if it is GONE, the parent will be gone even though other view's visibility are VISIBLE.

Is MediatorLiveData not best fit here? OR I mis-utilized it?

What could be the best solution for my case?

1

There are 1 best solutions below

0
On

Currently, when you update Visibility of the container, if the latest update of any view out of three is invisible, it set value as invisible even though previously any of three was visible. SO you need to update the Update() method. Something similar like this

val viewContainerVisibility = MediatorLiveData<Int>.apply {
        fun update() {
            if(firstViewVisibility.value == View.Visible || secondViewVisibility.value == View.Visible || thirdViewVisibility.value == View.Visible) 
{View.Visible}
else{
View.GONE //or INVISIBLE as required}
        }

        addSource(firstViewVisibility) {
            update()
        }

        addSource(secondViewVisibility) {
            update()
        }

        addSource(thirdViewVisibility) {
            update()
        }

        // and so on
    }