想象一下一个可以逐个进行投票的StackOverflow问题列表。每个问题都有一个计数器,显示其得票数。点击“赞成”按钮会使得该计数器加1,点击“反对”按钮会使得该计数器减1。这就是我尝试实现的基本思路。单个RecyclerView中每个项目的布局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)}"/>
@+id/decrease_quantity
类似于踩,@+id/quantity
类似于投票数,@+id/increase_quantity
类似于赞。 适配器:
class ListRvAdapter extends RecyclerView.Adapter<ListRvAdapter.ViewHolder> {
private List<Item> items;
private ListViewModel viewModel;
private LifecycleOwner lifecycleOwner;
ListRvAdapter(List<Item> items, ListViewModel viewModel, LifecycleOwner lifecycleOwner) {
this.items = items;
this.viewModel = viewModel;
this.lifecycleOwner = lifecycleOwner;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
RvItemBinding binding = RvItemBinding.inflate(layoutInflater, parent, false);
return new ViewHolder(binding, viewModel, lifecycleOwner);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.bind(items.get(position));
}
@Override
public int getItemCount() {
return items.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
private final RvItemBinding binding;
private ListViewModel viewModel;
private LifecycleOwner lifecycleOwner;
ViewHolder(RvItemBinding binding, ListViewModel viewModel, LifecycleOwner lifecycleOwner) {
super(binding.getRoot());
this.binding = binding;
this.viewModel = viewModel;
this.lifecycleOwner = lifecycleOwner;
}
public void bind(Item item) {
binding.setItem(item);
binding.setVm(viewModel);
binding.executePendingBindings();
binding.setLifecycleOwner(lifecycleOwner);
}
}
}
我省略了ViewModel,ListViewModel
,因为vm.decrementItemQuantity(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和DataBinding时,我会执行类似于
itemQuantityLiveData.setValue(item.quantity)
的操作,这将立即反映在XML中。但在这种情况下,我在我的ViewHolder中使用了bind(Item item)
方法,并且将item
对象作为变量传递到DataBinding布局,而不是作为表达式。我该如何解决这个问题?
notifyPropertyChanged()
方法。不要忘记从BaseObservable
类继承。 - Abbas