Use data binding to set View visibility

AndroidAndroid Databinding

Android Problem Overview


Trying to set visibility of View using custom variable, but error occurs: Identifiers must have user defined types from the XML file. visible is missing it. Is it possible to set view visibility using data binding? Thanks.

<data>
    <variable
        name="sale"
        type="java.lang.Boolean"/>
</data>

<FrameLayout android:visibility="@{sale ? visible : gone}"/>

Android Solutions


Solution 1 - Android

As stated in the Android Developer Guide, you need to do it like this:

<data>
    <import type="android.view.View"/>
    <variable
        name="sale"
        type="java.lang.Boolean"/>
</data>

<FrameLayout android:visibility="@{sale ? View.GONE : View.VISIBLE}"/>

Solution 2 - Android

In your layout:

<data>
    <variable
        name="viewModel"
        type="...."/>
</data>


<View
 android:layout_width="10dp"
 android:layout_height="10dp"
 android:visibility="@{viewModel.saleVisibility, default=gone}"/>

In your ViewModel java code:

@Bindable
public int getSaleVisibility(){
 return mSaleIndecator ? VISIBLE : GONE;
}

Solution 3 - Android

The problem is that visibility is an Integer on the View class, this means you have two ways to make this work:

  1. Use the View.VISIBLE and View.GONE constants. https://developer.android.com/topic/libraries/data-binding/index.html#imports
  2. Define a custom setter for visibility that takes a Boolean. https://developer.android.com/topic/libraries/data-binding/index.html#custom_setters

Possible implementation:

@BindingAdapter("android:visibility")
public static void setVisibility(View view, Boolean value) {
    view.setVisibility(value ? View.VISIBLE : View.GONE);
}

Which will make <FrameLayout android:visibility="@{sale}"/> work.

Solution 4 - Android

Similar to Kiskae solution. Put this method in a separate file, for instance, Bindings.kt:

@BindingAdapter("android:visibility")
fun View.bindVisibility(visible: Boolean?) {
    isVisible = visible == true
    // visibility = if (visible == true) View.VISIBLE else View.GONE
}

Then in layout XML:

<data>

    <variable
        name="viewModel"
        type="SomeViewModel" />
</data>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="@{viewModel.number == 1}" />

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKonstantin KonopkoView Question on Stackoverflow
Solution 1 - AndroidDavid ArtmannView Answer on Stackoverflow
Solution 2 - AndroidLior View Answer on Stackoverflow
Solution 3 - AndroidKiskaeView Answer on Stackoverflow
Solution 4 - AndroidCoolMindView Answer on Stackoverflow