Android 如何更新RecyclerView项中的绑定?
想象一个StackOverflow问题列表,这些问题可以单独进行上下表决。他们中的每一个人都有一个显示其投票数的计数。单击upvote将增加该计数1,单击downvote将减少该计数1。这就是我想要实现的目标的总体思路。RecyclerView中单个项目的布局,Android 如何更新RecyclerView项中的绑定?,android,android-databinding,android-livedata,android-viewmodel,Android,Android Databinding,Android Livedata,Android Viewmodel,想象一个StackOverflow问题列表,这些问题可以单独进行上下表决。他们中的每一个人都有一个显示其投票数的计数。单击upvote将增加该计数1,单击downvote将减少该计数1。这就是我想要实现的目标的总体思路。RecyclerView中单个项目的布局,rv_item.xml(为简洁起见进行了压缩): data> <variable name="item" type="com.mycodez.Item"/> <va
rv_item.xml
(为简洁起见进行了压缩):
data>
<variable
name="item"
type="com.mycodez.Item"/>
<variable
name="vm"
type="com.mycodez.ListViewModel" />
</data>
<Button
android:id="@+id/decrease_quantity"
android:onClick="@{() -> vm.decrementItemQuantity(item)}"/>
<TextView
android:id="@+id/quantity"
android:text="@{String.valueOf(item.quantity)}"
tools:text="1" />
<Button
android:id="@+id/increase_quantity"
android:onClick="@{() -> vm.incrementItemQuantity(item)}"/>
我省略了ViewModel,ListViewModel
,因为vm.DecrementeMQuantity(item)
和vm.incrementItemQuantity(item)
基本上是调用模型来更新数据库中的数量:
@Query("UPDATE items SET quantity=quantity + 1 WHERE id=:itemId")
Completable incrementQuantity(int itemId);
@Query("UPDATE items SET quantity=quantity - 1 WHERE quantity > 1 AND id=:itemId")
Completable decrementQuantity(int itemId);
因此,在模型中更新数量时,我不清楚应该如何更新特定RecyclerView项的UI以反映该更改。通常,在使用LiveData和数据绑定时,我会执行类似于itemQuantityLiveData.setValue(item.quantity)
的操作,这会立即反映在XML中。但是在本例中,我在ViewHolder中使用bind(Item Item)
方法,并且Item
对象作为变量而不是表达式传递给数据绑定布局
我如何解决这个问题 不必过度思考。在适配器实例上调用
notifyItemChanged(position)
是缺少的一部分。因此,如何将RecyclerView项的索引传递回适配器就成了一个问题
编辑rv_item.xml
以获取附加变量position
:
<data>
<variable
name="item"
type="com.mycodez.Item"/>
<!-- add this variable -->
<variable
name="position"
type="int"/>
<variable
name="vm"
type="com.mycodez.ListViewModel" />
</data>
public MutableLiveData<Event<Integer>> itemQuantityIncreased = new MutableLiveData<>();
然后ListRvAdapter
ViewHolder
中的bind
方法变为:
public void bind(Item item, int position) { // new argument
binding.setItem(item);
binding.setPosition(position); // pass position to the layout
binding.setVm(viewModel);
binding.executePendingBindings();
binding.setLifecycleOwner(lifecycleOwner);
}
在适配器的onBindViewHolder
中传递新参数,如下所示:
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.bind(items.get(position), position);
}
最后,在列表适配器中添加两种方法,分别增加和减少数量:
public void increaseQuantity(int position) {
Item item = items.get(position);
item.quantity += 1;
notifyItemChanged(position);
}
public void decreaseQuantity(int position) {
Item item = items.get(position);
item.quantity -= 1;
notifyItemChanged(position);
}
所有这些就绪后,当单击按钮@+id/increase\u quantity
时,将触发vm.incrementItemQuantity(item,position)
。在MVVM设置中,ViewModel将有一个用于位置的LiveData事件对象:
<data>
<variable
name="item"
type="com.mycodez.Item"/>
<!-- add this variable -->
<variable
name="position"
type="int"/>
<variable
name="vm"
type="com.mycodez.ListViewModel" />
</data>
public MutableLiveData<Event<Integer>> itemQuantityIncreased = new MutableLiveData<>();
public MutableLiveData itemQuantityIncreased=new MutableLiveData();
调用vm.incrementItemQuantity(item,position)
将设置该对象的值:
itemQuantityIncremented.setValue(新事件(位置))
最后,视图将在ViewModel的itemQuantityIncreased
LiveData对象上有一个观察者。因为事件会发送RecyclerView项的位置,所以视图可以获取该位置并在适当的位置调用adapter.increaseQuantity(position)
<代码>适配器。减少数量(位置)
的工作原理相同。在您的型号上调用notifyPropertyChanged()
。别忘了从BaseObservable
扩展。请进一步详细说明。我已经在使用LiveData了。你是不是建议我改为BaseObservable?否则我会在问题的底部添加更多信息。请检查。您能显示您正在更新数量字段的代码吗?视图模型,或者模型。啊,没关系。我自己设法解决了这个问题,我刚刚发布了我的解决方案作为答案。谢谢你的来访。谢谢你详尽的评论。是否真的没有更简单的方法可以直接从viewholder中执行而不涉及listadapter?上面的解决方案很合适,但我有不同的场景,比如不是upvote和down vote,而是我从api获得的视图计数,另外我不想在该位置通知整个项目,我只想更新视图计数文本,如何做到这一点?