141

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}"/>
Konstantin Konopko
  • 5,229
  • 4
  • 36
  • 62
  • Refer [Android Data Binding: visibility on include tag](https://stackoverflow.com/questions/35723823/android-data-binding-visibility-on-include-tag) – Ravi Jun 08 '17 at 05:00

4 Answers4

339

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}"/>
tynn
  • 38,113
  • 8
  • 108
  • 143
David Artmann
  • 4,272
  • 1
  • 16
  • 24
69

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;
}
Lior
  • 832
  • 6
  • 6
50

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.

Kiskae
  • 24,655
  • 2
  • 77
  • 74
5

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}" />
CoolMind
  • 26,736
  • 15
  • 188
  • 224