Android数据绑定疑问

时间:2017-04-05 16:11:04

标签: android data-binding android-recyclerview android-context android-databinding

在我看来,Android数据绑定是一个有趣的工具,但它与Android的(过度)复杂架构并没有很好的结合。许多示例或教程仅显示了一些显然有效的基本场景,但是当事情变得更难时,就会出现问题。

例如:许多视图(如RecyclerView或ViewPager)需要需要Context的适配器或装饰器,将Context传递给每个ViewModel似乎是错误的,因为它会破坏层的分离。

ViewFlipper:如何通过绑定ViewModel的属性来显示next或previous?

如何将RecyclerView与LinearLayout,ItemAnimation和ItemDecoration绑定?你能在工作中展示一些真实的Android数据绑定的复杂例子吗?

1 个答案:

答案 0 :(得分:4)

您可能对这两篇文章感兴趣:

使用与RecyclerView的数据绑定: https://medium.com/google-developers/android-data-binding-recyclerview-db7c40d9f0e4

在没有RecyclerView的列表中使用数据绑定(例如LinearLayout): https://medium.com/google-developers/android-data-binding-list-tricks-ef3d5630555e

使用ItemDecoration,您必须添加自己的BindingAdapter,因为RecyclerView允许多个项目装饰。这样的事情应该有效:

@BindingAdapter("itemDecoration")
public static void setItemDecoration(RecyclerView view, ItemDecoration old,
        ItemDecoration newVal) {
    if (old != null) {
        view.removeItemDecoration(old);
    }
    if (newVal != null) {
        view.addItemDecoration(newVal);
    }
}

关于上下文的问题有点令人困惑。我试图想象你将如何在数据绑定中使用Context。数据绑定表达式不允许new,因此您无法以这种方式创建一个。也许你正在考虑使用一些表示法来代替:

@BindingAdapter("dividerDirection")
public static void setItemDecoration(RecyclerView view, int oldDirection, int newDirection) {
    if (oldDirection != newDirection) {
        ItemDecoration decoration =
                new DividerItemDecoration(view.getContext(), newDirection);
        ItemDecoration old = ListenerUtil.trackListener(view, decoration, R.id.decoration);
        if (old != null) {
            view.removeItemDecoration(old);
        }
        view.addItemDecoration(decoration);
    }
}

它会受到这样的约束:

<android.support.v7.widget.RecyclerView
     app:dividerDirection="@{DividerItemDecoration.HORIZONTAL}" .../>

对于其他用途,您会在布局中自动为您提供内置的“上下文”变量,并且可以将其传递给您调用的任何方法。它是绑定视图层次结构的根视图的上下文,应该可以满足您的大多数需求。在大多数用途中,您不需要传递模型中的上下文。

我希望这也应该回答你关于ItemAnimator的问题,尽管你不需要特殊的BindingAdapter来使用属性,因为它已经有了一个setter:

<android.support.v7.widget.RecyclerView
     app:itemAnimator="@{model.animator}" .../>