DataBinding visibility depending on a list size

I just faced the same problem and setting visibility directly by item.employees.size (without parentheses) worked for me like a charm.

android:visibility="@{item.employees.size > 0 ? View.VISIBLE : View.GONE}"


After recreating a sample program OP found out, that he was setting a wrong variable.

Sample:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = 
                DataBindingUtil.setContentView(this, R.layout.activity_main);
        Company company1 = new Company();
        Company company2 = new Company();

        ArrayList<String> employee2 = new ArrayList<>();
        employee2.add("First");
        company2.setEmployees(employee2);

        binding.setCompany1(company1);
        binding.setCompany2(company2);
    }

    @BindingConversion
    public static int listToVisibility(List list) {
        //Also works with Collection
        return (list == null || list.isEmpty()) ? View.INVISIBLE : View.VISIBLE;
    }
}

Xml:

<layout>
    <data>
        <variable
            name="company1"
            type="com.may.amy.bindingconversiontest.Company" />
        <variable
            name="company2"
            type="com.may.amy.bindingconversiontest.Company" />
    </data>
    <TextView
        android:text="Company1 has employees"
        android:visibility="@{company1.employees}"/>

    <TextView
        android:text="Company2 has employees"
        android:visibility="@{company2.employees}"/>
</layout>

My preferred solution to the "visibility problem" is to use

ObservableInt listVisibility = new ObservableInt(View.GONE);

in my ViewModel.

boolean visible = list.size() > 0 || showHeaderIfEmpty; 
listVisibility .set(visible ? View.VISIBLE : View.GONE);  

The advantage is that my condition can easily depend on many factors instead of only the list size.

In xml:

android:visibility="@{listVisibility}"

Of course this may need to be updated, or used with an ObservableList.


Let's call a new file "BindingAdapters", since possibly you will be using it on other places.

object BindingAdapters {
    @JvmStatic
    @BindingAdapter("visibleGone")
    fun showHide(view: View, show: Boolean) {
        view.visibility = if (show) View.VISIBLE else View.GONE
    }
}

on the XML you just have to do the following:

app:visibleGone="@{viewModel.list.isNotEmpty()}"