Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use data binding to set View visibility

People also ask

Should I use view binding or data binding?

View binding and data binding both generate binding classes that you can use to reference views directly. However, view binding is intended to handle simpler use cases and provides the following benefits over data binding: Faster compilation: View binding requires no annotation processing, so compile times are faster.

What is data binding used for?

In Android, the Data Binding Library is a support library that allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically.


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}"/>

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;
}

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.


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}" />