Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using LiveData to set visibility of TextView

I want to toggle the visibility of a TextView using LiveData. There have been a few other posts on setting the visibility with databinding, but these use Observables, whereas I want to leverage the (newer) LiveData. In particular, use a LiveData.

Using this documentation, and a few SO posts, I have already learned that you should correctly align your getter of your observable (LiveData) so that the return type matches the type expected by the setter for the View attribute you want to set. Specifically:

  • setVisibility() of View requires an int, whereas I have a LiveData member (so the getter in my ViewModel will also return this type)
  • converting this Boolean to View.VISIBLE and VIEW.GONE is possible using a ternary operator. I should also add safeUnbox() in my XML expression to make it a primitive boolean

Using these insights, in my ViewModel class, I have defined:

MutableLiveData<Boolean> textHintVisible;

After pressing a button, I set this value to False:

textHintVisible.postValue(false);

(note, I also tried with setValue())

Then, in my layout XML, I have included:

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

But still, my TextView is always visible. To debug, I have added an observer in my activity, and this confirms that my boolean is correctly toggled between true and false:

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

But my TextView stays visible all the time. What am I doing wrong? Is it impossible to use LiveData for this? Should I use an additional Converter? Or is my code in principle correct, but is this a bug in Android Studio? Any help is much appreciated.

like image 369
user3820186 Avatar asked Sep 07 '18 19:09

user3820186


People also ask

Can I use LiveData without ViewModel?

To answer your question, No, It is not mandatory to use LiveData always inside ViewModel, it is just an observable pattern to inform the caller about updates in data. If you have something which won't be changed frequently and can be accessed by its instance. You can completely ignore wrapping it inside LiveData.

How do you observe LiveData in activity?

You usually create an Observer object in a UI controller, such as an activity or fragment. Attach the Observer object to the LiveData object using the observe() method. The observe() method takes a LifecycleOwner object. This subscribes the Observer object to the LiveData object so that it is notified of changes.

What is LiveData and ViewModel?

ViewModel instances survive device configuration changes. LiveData : A data holder class that follows the observer pattern, which means that it can be observed. Always holds/caches latest version of data. Notifies its observers when the data has changed. LiveData is lifecycle aware.


1 Answers

One thing I have in mind is - have you set your binding to observe liveData? As per documentation you have to set the binding layout to observe lifecycle binding.setLifecycleOwner(this)

like image 54
mlykotom Avatar answered Nov 09 '22 03:11

mlykotom