Android 数据绑定疑惑
Android Data Binding doubts
在我看来,Android 数据绑定是一个有趣的工具,但它与 Android 的(过于)复杂的体系结构结合得不是很好。许多示例或教程只展示了一些显然有效的基本场景,但当事情变得更难时,问题就会出现。
例如:许多视图(如 RecyclerView 或 ViewPager)需要需要 Context 的适配器或装饰器,将 Context 传递给每个 ViewModel 似乎是错误的,因为它破坏了层的分离。
ViewFlipper:如何仅通过绑定 ViewModel 的 属性 来显示下一个或上一个?
如何将 RecyclerView 与 LinearLayout、ItemAnimation 和 ItemDecoration 绑定?您能否展示一些 Android 数据绑定在工作中的真实复杂示例?
您可能对这两篇文章感兴趣:
关于在 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}" .../>
对于其他用途,您会自动获得布局中的内置 "context" 变量,您可以将其传递给您调用的任何方法。它是绑定视图层次结构的根视图的上下文,应该可以满足您的大部分需求。对于大多数用途,您不需要在模型中传递上下文。
我希望这也能回答你关于 ItemAnimator 的问题,尽管你不需要特殊的 BindingAdapter 来使用属性,因为它已经有 setter:
<android.support.v7.widget.RecyclerView
app:itemAnimator="@{model.animator}" .../>
在我看来,Android 数据绑定是一个有趣的工具,但它与 Android 的(过于)复杂的体系结构结合得不是很好。许多示例或教程只展示了一些显然有效的基本场景,但当事情变得更难时,问题就会出现。
例如:许多视图(如 RecyclerView 或 ViewPager)需要需要 Context 的适配器或装饰器,将 Context 传递给每个 ViewModel 似乎是错误的,因为它破坏了层的分离。
ViewFlipper:如何仅通过绑定 ViewModel 的 属性 来显示下一个或上一个?
如何将 RecyclerView 与 LinearLayout、ItemAnimation 和 ItemDecoration 绑定?您能否展示一些 Android 数据绑定在工作中的真实复杂示例?
您可能对这两篇文章感兴趣:
关于在 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}" .../>
对于其他用途,您会自动获得布局中的内置 "context" 变量,您可以将其传递给您调用的任何方法。它是绑定视图层次结构的根视图的上下文,应该可以满足您的大部分需求。对于大多数用途,您不需要在模型中传递上下文。
我希望这也能回答你关于 ItemAnimator 的问题,尽管你不需要特殊的 BindingAdapter 来使用属性,因为它已经有 setter:
<android.support.v7.widget.RecyclerView
app:itemAnimator="@{model.animator}" .../>