Android 数据绑定 ObservableList 行为问题
Android data binding ObservableList behaviour issue
我发现很难发现 android.databinding.ObservableList
作为数据绑定功能的真正存在理由。
起初它看起来像是一个很酷的显示列表的工具,通过 data binding,通过 xml
添加它们到 RecyclerView
。
为此,我做了一个 BindingAdapter 这样的:
@BindingAdapter(value = {"items"}, requireAll = false)
public static void setMyAdapterItems(RecyclerView view, ObservableList <T> items) {
if(items != null && (view.getAdapter() instanceof MyAdapter)) {
((GenericAdapter<T>) view.getAdapter()).setItems(items);
}
}
这样,我可以在设置了 MyAdapter
的 RecyclerView
中使用属性 app:items
来更新它的项目。
现在 ObservableList
的最佳功能是您可以向它添加一个 OnListChangedCallback
,它处理其中 RecyclerView
到 add/move/remove/change 项中可用的相同事件无需实际重新加载整个列表。
所以我想实现的逻辑是:
- 我从一个空的开始
MyAdapter
- 当我的项目从我的 API 中获取时,我实例化一个
ObservableArrayList
包装它们并将其传递给 binding
- 数据绑定调用我的
BindingAdapter
将项目传递给 MyAdapter
- 当
MyAdapter
收到新项目时,它会清除旧项目并在收到的 ObservableList
中添加 OnListChangedCallback
以处理微更改
- 如果
ObservableList
有任何变化,MyAdapter
将相应地改变而不完全刷新
- 如果我想显示一组完全不同的相同项目类型,我可以重新设置
binding
变量,这样 BindingAdapter
将再次调用 MyAdapter
项目将完全改变。
例如,如果我想显示 Game
类型的项目,我有两个不同的列表:"owned games" 和 "wishlist games",我可以调用 binding.setItems(whateverItems)
完全刷新显示的项目,但是例如,如果我在列表中移动 "wishlist games" 以按相关性组织它们,则只会在每个列表中执行微更改,而不会刷新整个内容。
事实证明这个想法是不可行的,因为每次对 ObservableList
进行一次更改时,数据绑定都会重新执行 BindingAdapter
,因此例如我观察到休闲行为:
- 我从一个空的开始
MyAdapter
- 当我的项目从我的 API 中获取时,我实例化一个
ObservableArrayList
包装它们并将其传递给 binding
- 数据绑定调用我的
BindingAdapter
将项目传递给 MyAdapter
- 当
MyAdapter
收到新项目时,它会清除旧项目并在收到的 ObservableList
中添加 OnListChangedCallback
以处理微更改
- 如果
ObservableList
中有任何变化,将再次调用 BindingAdapter
,因此 MyAdapter
再次接收整个列表并完全刷新。
这种行为对我来说似乎很糟糕,因为它阻止了 ObservableList
在数据绑定 xml
中可用。我无法认真地找出这种行为是可取的合法案例。
我查了一些例子:here and
在第一个 link 中,所有示例都直接使用 ObservableList
到 Adapter
,甚至没有传递表单 xml
和实际数据绑定,而在代码中 linked 在 SO 答案中,开发人员基本上做了我尝试做的同样的事情,添加:
if (this.items == items){
return;
}
在他的开头 Adapter.setItems(ObservableList<T> items)
丢弃所有由于 ObservableList
.
中的简单更改而调用该方法的情况
这种行为的必要性是什么?在某些情况下,这种行为是可取的?我觉得 ObservableList
是一个添加了数据绑定的功能,并且非常有用,除非与实际数据绑定一起使用,在这种情况下,它会迫使您抵御它的行为。
如果我在 xml
数据标签和 BindingAdapter
签名中将它声明为简单的 List
,那么我可以将它转换回 MyAdapter
中的 ObservableList
并且它工作得很好,但这是一个非常糟糕的黑客攻击。
如果它只是一个独立于数据绑定的功能,而不在每次更改时触发绑定,在我看来会好得多。
根据文档 https://developer.android.com/topic/libraries/data-binding/index.html#observable_collections 中提供的示例,ObservableList 用于使用键整数访问它的项目,即:
<data>
<import type="android.databinding.ObservableList"/>
<import type="com.example.my.app.Fields"/>
<variable name="user" type="ObservableList<Object>"/>
</data>
…
<TextView
android:text='@{user[Fields.LAST_NAME]}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
因此,当 ObservableList
内部发生更改时,它会触发 BindingAdapter 更新 UI。我认为这是在 DataBinding 处于开发状态时暂时使用 ObservableList
的主要目的。也许将来 DataBinding 会更新为一个新的 SomeObservableList
,它将用于 RecyclerView。
同时,您可以使用 if (this.items == items){return;}
如果它适合您,或者重新考虑您使用 ObservableList
.
的逻辑
我发现很难发现 android.databinding.ObservableList
作为数据绑定功能的真正存在理由。
起初它看起来像是一个很酷的显示列表的工具,通过 data binding,通过 xml
添加它们到 RecyclerView
。
为此,我做了一个 BindingAdapter 这样的:
@BindingAdapter(value = {"items"}, requireAll = false)
public static void setMyAdapterItems(RecyclerView view, ObservableList <T> items) {
if(items != null && (view.getAdapter() instanceof MyAdapter)) {
((GenericAdapter<T>) view.getAdapter()).setItems(items);
}
}
这样,我可以在设置了 MyAdapter
的 RecyclerView
中使用属性 app:items
来更新它的项目。
现在 ObservableList
的最佳功能是您可以向它添加一个 OnListChangedCallback
,它处理其中 RecyclerView
到 add/move/remove/change 项中可用的相同事件无需实际重新加载整个列表。
所以我想实现的逻辑是:
- 我从一个空的开始
MyAdapter
- 当我的项目从我的 API 中获取时,我实例化一个
ObservableArrayList
包装它们并将其传递给binding
- 数据绑定调用我的
BindingAdapter
将项目传递给MyAdapter
- 当
MyAdapter
收到新项目时,它会清除旧项目并在收到的ObservableList
中添加OnListChangedCallback
以处理微更改 - 如果
ObservableList
有任何变化,MyAdapter
将相应地改变而不完全刷新 - 如果我想显示一组完全不同的相同项目类型,我可以重新设置
binding
变量,这样BindingAdapter
将再次调用MyAdapter
项目将完全改变。
例如,如果我想显示 Game
类型的项目,我有两个不同的列表:"owned games" 和 "wishlist games",我可以调用 binding.setItems(whateverItems)
完全刷新显示的项目,但是例如,如果我在列表中移动 "wishlist games" 以按相关性组织它们,则只会在每个列表中执行微更改,而不会刷新整个内容。
事实证明这个想法是不可行的,因为每次对 ObservableList
进行一次更改时,数据绑定都会重新执行 BindingAdapter
,因此例如我观察到休闲行为:
- 我从一个空的开始
MyAdapter
- 当我的项目从我的 API 中获取时,我实例化一个
ObservableArrayList
包装它们并将其传递给binding
- 数据绑定调用我的
BindingAdapter
将项目传递给MyAdapter
- 当
MyAdapter
收到新项目时,它会清除旧项目并在收到的ObservableList
中添加OnListChangedCallback
以处理微更改 - 如果
ObservableList
中有任何变化,将再次调用BindingAdapter
,因此MyAdapter
再次接收整个列表并完全刷新。
这种行为对我来说似乎很糟糕,因为它阻止了 ObservableList
在数据绑定 xml
中可用。我无法认真地找出这种行为是可取的合法案例。
我查了一些例子:here and
在第一个 link 中,所有示例都直接使用 ObservableList
到 Adapter
,甚至没有传递表单 xml
和实际数据绑定,而在代码中 linked 在 SO 答案中,开发人员基本上做了我尝试做的同样的事情,添加:
if (this.items == items){
return;
}
在他的开头 Adapter.setItems(ObservableList<T> items)
丢弃所有由于 ObservableList
.
这种行为的必要性是什么?在某些情况下,这种行为是可取的?我觉得 ObservableList
是一个添加了数据绑定的功能,并且非常有用,除非与实际数据绑定一起使用,在这种情况下,它会迫使您抵御它的行为。
如果我在 xml
数据标签和 BindingAdapter
签名中将它声明为简单的 List
,那么我可以将它转换回 MyAdapter
中的 ObservableList
并且它工作得很好,但这是一个非常糟糕的黑客攻击。
如果它只是一个独立于数据绑定的功能,而不在每次更改时触发绑定,在我看来会好得多。
根据文档 https://developer.android.com/topic/libraries/data-binding/index.html#observable_collections 中提供的示例,ObservableList 用于使用键整数访问它的项目,即:
<data>
<import type="android.databinding.ObservableList"/>
<import type="com.example.my.app.Fields"/>
<variable name="user" type="ObservableList<Object>"/>
</data>
…
<TextView
android:text='@{user[Fields.LAST_NAME]}'
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
因此,当 ObservableList
内部发生更改时,它会触发 BindingAdapter 更新 UI。我认为这是在 DataBinding 处于开发状态时暂时使用 ObservableList
的主要目的。也许将来 DataBinding 会更新为一个新的 SomeObservableList
,它将用于 RecyclerView。
同时,您可以使用 if (this.items == items){return;}
如果它适合您,或者重新考虑您使用 ObservableList
.