行为说明:使用LiveData使用DiffUtil更新适配器

时间:2019-10-06 00:25:46

标签: android-studio android-livedata android-diffutils

我正在使用self.droplist = tk.OptionMenu(. . ., command = lambda _: self.new_label()) 来更新我的回收站视图,如下所示:

LiveData

我正在使用viewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class); viewModel.getPurchaseList().observe(getViewLifecycleOwner(), new Observer<List<ProductsObject>>() { @Override public void onChanged(@Nullable List<ProductsObject> productsObjects) { adapter.submitList(productsObjects); //adapter.notifyDataSetChanged(); } }); 来更改我的FloatActionButton的值,如下所示:

MutableLiveData

所有数据都会更改,并且FloatingActionButton fab = view.findViewById(R.id.cart_fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { viewModel.setPurchasePrice(0, 101.2); } }); 被按预期方式调用,但是只有在启用onChanged时才会更新recyclerview

如果我在FAB内创建新的adapter.notifyDataSetChanged();提交新列表,则无需调用ProductsObject即可更新recyclerview,如下所示:

adapter.notifyDataSetChanged();

我很高兴有人能解释为什么。

这是我的适配器:

FloatingActionButton fab = view.findViewById(R.id.cart_fab);
fab.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //viewModel.setPurchaseAmount(0, 101.2);
        ProductsObject prod = new ProductsObject("6666", 5, 152.2, "new product");
        List<ProductsObject> prodList = new ArrayList<>();
        prodList.add(prod);
        adapter.submitList(prodList);
    }
});

这是我的public class CartFragAdapter extends RecyclerView.Adapter<CartFragAdapter.CartFragViewHolder> { private static final String TAG = "debinf PurchaseAdap"; private static final DiffUtil.ItemCallback<ProductsObject> DIFF_CALLBACK = new DiffUtil.ItemCallback<ProductsObject>() { @Override public boolean areItemsTheSame(@NonNull ProductsObject oldProduct, @NonNull ProductsObject newProduct) { Log.i(TAG, "areItemsTheSame: old is "+oldProduct.getCode()+" ; new is "+newProduct.getCode()); return oldProduct.getCode().equals(newProduct.getCode()); } @Override public boolean areContentsTheSame(@NonNull ProductsObject oldProduct, @NonNull ProductsObject newProduct) { Log.i(TAG, "areContentsTheSame: old is "+oldProduct.getPrice()+" ; new is "+newProduct.getPrice()); return oldProduct.getPrice() == newProduct.getPrice(); } }; private AsyncListDiffer<ProductsObject> differ = new AsyncListDiffer<ProductsObject>(this, DIFF_CALLBACK); @NonNull @Override public CartFragViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_purchase, parent, false); return new CartFragViewHolder(view); } @Override public void onBindViewHolder(@NonNull CartFragViewHolder holder, int position) { final ProductsObject purchaseList = differ.getCurrentList().get(position); holder.mCode.setText(purchaseList.getCode()); holder.mPrice.setText(String.valueOf(purchaseList.getPrice())); holder.mDescription.setText(purchaseList.getDescription()); } @Override public int getItemCount() { Log.i(TAG, "getItemCount"); return differ.getCurrentList().size(); } public void submitList(List<ProductsObject> products){ Log.i(TAG, "submitList: products.size is "+products.size()); differ.submitList(products); } public class CartFragViewHolder extends RecyclerView.ViewHolder { public TextView mCode, mPrice, mDescription; public CartFragViewHolder(@NonNull View itemView) { super(itemView); mCode = (TextView) itemView.findViewById(R.id.item_productCode); mPrice = (TextView) itemView.findViewById(R.id.item_productPrice); mDescription = (TextView) itemView.findViewById(R.id.item_productDescription); } } }

ViewModel

1 个答案:

答案 0 :(得分:0)

AsyncListDiffer仅保存列表的引用。这意味着,如果您提交修改后的列表而不是提交新列表,AsncListDiffer将无法检测到任何差异,因为前一个列表和新列表都引用具有相同项目的相同列表。< / p>

要解决此问题,您需要创建一个新列表和新项目。更改MyViewModel#setPurchasePrice,如下所示:

    public void setPurchasePrice(int position, double price) {
        List<ProductsObject> itemList = purchaseList.getValue();
        if (itemList != null && itemList.get(position) != null) {

            List<ProductsObject> newList = new ArrayList<>();

            for (int i = 0; i < itemList.size(); i++) {
                ProductsObject prevProd = itemList.get(i);

                if (i != position) {
                    newList.add(prevProd);
                } else {
                    ProductsObject newProd = new ProductsObject(..., price, ...);
                    newList.add(newProd);
                }
            }
            purchaseList.postValue(newList);
        }

    }