Search code examples
androidandroid-databinding

Databinding displays unpopulated value while waiting for the value to be populated in Android


I am using databinding to display text on TextView using ternary syntax.

android:text="@{vm.value.firstValue != null ? vm.value.firstValue.toString() : @string/source1}"

This code displays @string/source1 upon first loading of a fragment before the vm.value completely being loaded by network call. Then, it display vm.value.firstValue when the network call succeeds. However, I want to display the @string/source1 only when network call fails.
I wonder if it is okay to display nothing(keep it empty) while waiting for the network call to be done successfully. then, populate TextView based on if a network call success or not. If this sounds okay, I would like to know how to acheive that using databinding.


Solution

  • The databinding framework cannot discern between a null value that is caused by the loading not being finished yet and a null value that is the result after loading. So you would have to implement such a discernment logic yourself.

    You could introduce a new isLoading boolean in your ViewModel. Whenever you trigger a loading operation, set isLoading=true, and after the loading is finished, set isLoading=false. Then use the following condition in your XML:

    android:text="@{vm.isLoading ? (@string/textIsLoading) : (vm.value.firstValue != null ? vm.value.firstValue.toString() : @string/source1)}"
    

    You probably can further simplify the above statement like this:

    android:text="@{vm.isLoading ? (@string/textIsLoading) : (vm.value.firstValue ?? @string/source1)}"
    

    For an explanation of the ?? operator, see this StackOverflow question.


    If you don't want to create a new boolean variable in your ViewModel, you also can also initialize your value.firstValue variable to a default string that is displayed while loading:

    value.firstValue = "Text is loading..."  // replace with R.string later
    

    When loading the text fails, just set

    value.firstValue = null
    

    And then use the following statement in your XML:

    android:text="@{vm.value.firstValue ?? @string/source1}"