DataBinding可见性取决于列表大小

时间:2017-04-06 09:43:50

标签: android android-databinding

我有一个在数据绑定中用作变量的对象。

public class Company {
    private int id;
    private String name;
    private List<Employee> employees;
    private List<Room> rooms;
}


<data>
     <variable
         name="item"
         type="com.blablabla.model.entity.Company"/>

</data>

想要根据列表大小(员工)更改视图的可见性,因此如果列表为null或为空 - 可见性为GONE,否则为可见。

到目前为止我尝试了什么:
1)直接设置可见性:

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

事实上,能见度总是很高。

当然我导入了

<import type="android.view.View"/>

2)使用BindingConverter:

@BindingConversion
    public static int convertCollectionToVisibility(Collection collection) {
        Log.d(TAG, "collection: " + (collection == null ? "null" : collection.size()));
        return collection == null || collection.isEmpty() ? View.GONE : View.VISIBLE;
    }

然后在布局中:

android:visibility="@{item.employees}"

这里的日志显示,该集合始终为null。 但绝对不是

Company company = new Company(1, "Company 1");
List<Employee> employees = new ArrayList<>();
        employees.add(new Employee(i, "Jack", "Floyd"));
        company.setEmployees(employees);
mBinding.setItem(company);

有什么想法吗?

5 个答案:

答案 0 :(得分:4)

我刚遇到同样的问题,并且item.employees.size(没有括号)直接设置可见性就像魅力一样为我工作。

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

答案 1 :(得分:2)

重新创建sample program OP后,他正在设置一个错误的变量。

样品:

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>

我对&#34;可见性问题的首选解决方案&#34;是用

ObservableInt listVisibility = new ObservableInt(View.GONE);

在我的ViewModel中。

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

优点是我的情况很容易取决于许多因素而不仅仅是列表大小。

在xml中:

android:visibility="@{listVisibility}"

当然,这可能需要更新,或与ObservableList一起使用。

答案 2 :(得分:1)

我们叫一个新文件“ BindingAdapters”,因为您可能会在其他地方使用它。

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

在XML上,您只需执行以下操作:

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

答案 3 :(得分:0)

我没有设法直接从ViewModel访问列表,例如:

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

但是,解决我问题的方法是:

  1. 在xml上创建boolean类型:
<data>
...
  <variable
    name="hasItens"
    type="boolean" />
...
</data
  1. 绑定hasItens关于适配器的更新:
vm.list.observe(viewLifecycleOwner) { list ->
            container.hasItens = !list.isNullOrEmpty()
            adapter.submitList(builtDates)
}
  1. 创建您的BindAdapter
@BindingAdapter("isGone")
fun bindIsGone(view: View, isGone: Boolean) {
    view.visibility = if (isGone) {
        View.GONE
    } else {
        View.VISIBLE
    }
}
  1. 在“视图”上设置可见性
<RecyclerView
  android:id="@+id/recyclerId"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  app:isGone="@{!hasItens}" />

答案 4 :(得分:0)

我按以下方式使用,它对我有用:

android:visibility="@{viewModel.data.empty ? View.GONE : View.VISIBLE}"

请告诉我是否有帮助!