notifyItemChanged 方法在 RecyclerView 中不会调用 onBindViewHolder。

14

我的代码如下所示:

public class PopularItemsAdapter extends RecyclerView.Adapter<PopularItemsAdapter.MyViewHolder>
        implements MyCartListener {

    private Context mContext;
    private List<FoodTruckItem> foodTruckItemList;
    private boolean isClickable = false;
    private OnItemClickListener listener;
    private List<FoodtruckInfo> foodtruckInfoList = new ArrayList<>();
    private List<FoodTruckItem> sessionItem = new ArrayList<>();
    private boolean isConflictResolved = false;
    public int position = -1;


    @Override
    public void itemUpdated(int quantity, String itemId) {
        for (int i = 0; i < foodTruckItemList.size(); i++) {
            if (itemId.equals(foodTruckItemList.get(i).getItemId())) {
                foodTruckItemList.get(i).setItemQuantityOrdered(quantity);
//                notifyDataSetChanged();
            }
        }
    }

    @Override
    public void itemRemoved(String itemId) {
        for (int j = 0; j < foodTruckItemList.size(); j++) {
            if (itemId.equals(foodTruckItemList.get(j).getItemId())) {
                foodTruckItemList.remove(j);
//                notifyDataSetChanged();
            }
        }
    }

    public void addConflictItem(int position) {
        isConflictResolved = true;
        notifyItemChanged(position);
    }

    public interface OnItemClickListener {
        void onItemClick(FoodTruckItem foodTruckItem, FoodtruckInfo foodtruckInfo);

        void showSnackBar(int items, boolean added, int position);

        void showRestaurentClosed();

        void showWarningDialog(int position);
    }


    public void addFoodInfo(List<FoodtruckInfo> foodtruckInfos) {
        foodtruckInfoList.addAll(foodtruckInfos);
    }


    public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView itemName, foodPrice, addText, quantityText, addQuantity, removeQuantity;
        public ImageView itemImage, itemTag;
        public LinearLayout addLayout;

        public MyViewHolder(View view) {
            super(view);
            itemTag = (ImageView) view.findViewById(R.id.itemTag);
            itemImage = (ImageView) view.findViewById(R.id.itemImage);
            itemName = (TextView) view.findViewById(R.id.itemName);
            foodPrice = (TextView) view.findViewById(R.id.foodPrice);
            addText = (TextView) view.findViewById(R.id.addText);
            addLayout = (LinearLayout) view.findViewById(R.id.addLayout);
            quantityText = (TextView) view.findViewById(R.id.quantityText);
            addQuantity = (TextView) view.findViewById(R.id.addQuantity);
            removeQuantity = (TextView) view.findViewById(R.id.removeQuantity);
            view.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            FoodtruckInfo foodtruckInfo = new FoodtruckInfo();
            //passing the clicked position to the parent class
            for (FoodtruckInfo info : foodtruckInfoList) {
                if (info.getItemId().equals(foodTruckItemList.get(getAdapterPosition()).getItemId())) {
                    foodtruckInfo = info;
                }
            }
            listener.onItemClick(foodTruckItemList.get(getAdapterPosition()), foodtruckInfo);
        }
    }


    public PopularItemsAdapter(Context mContext, List<FoodTruckItem> foodTruckItemList, OnItemClickListener listener) {
        this.mContext = mContext;
        this.foodTruckItemList = foodTruckItemList;
        this.listener = listener;
        MyCart.getInstance().addListener(this);
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.card_view_popular_items, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
        final FoodTruckItem foodTruckItem = foodTruckItemList.get(position);
        if (SessionManager.get(mContext).getFoodTruckItemList() != null) {
            sessionItem = SessionManager.get(mContext).getFoodTruckItemList();
            for (FoodTruckItem item : sessionItem) {
                if (item.getItemId().equals(foodTruckItem.getItemId())) {
//                    holder.itemTag.setText("MY FAVOURITE");
                    holder.itemTag.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_favorite));
                }
            }
        }

        holder.itemName.setText(foodTruckItem.getItemName());
//        holder.itemTag.setText(foodTruckItem.getSpecialTag());
        holder.foodPrice.setText("$" + String.valueOf(foodTruckItem.getItemPrice()));
        Picasso.Builder builder = new Picasso.Builder(mContext);
        builder.listener(new Picasso.Listener() {
            @Override
            public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
                exception.printStackTrace();
            }
        });
        if (!TextUtils.isEmpty(foodTruckItem.getItemImg())) {
            builder.build().load(foodTruckItem.getItemImg()).into(holder.itemImage);
        }
        holder.addText.setOnClickListener(new View.OnClickListener() {
            FoodtruckInfo info = new FoodtruckInfo();

            @Override
            public void onClick(View v) {
                for (int l = 0; l < foodtruckInfoList.size(); l++) {
                    if (foodtruckInfoList.get(l).getItemId().equals(foodTruckItem.getItemId())) {
                        if (foodtruckInfoList.get(l).getOrderStatus() == 0) {
                            isClickable = true;
                        } else {
                            isClickable = false;
                        }
                    }
                }
                if (isClickable) {
                    String foodTruckId = null;
                    if (MyCart.getInstance().getFoodTruckId() != null) {
                        foodTruckId = MyCart.getInstance().getFoodTruckId();
                        if (!foodTruckId.equals(foodtruckInfoList.get(position).getFoodTruckId())) {
                            listener.showWarningDialog(position);
                        } else {
                            addItem(holder, position, foodTruckItem);
                        }
                    } else {
                        isConflictResolved = false;
                        addItem(holder, position, foodTruckItem);
                    }
                } else {
                    listener.showRestaurentClosed();
                }

                if (isConflictResolved) {
                    isConflictResolved = false;
                    addItem(holder, position, foodTruckItem);
                }
            }
        });

        holder.addQuantity.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int quantity = foodTruckItem.getItemQuantityOrdered();
                quantity += 1;
                holder.quantityText.setText(String.valueOf(quantity));
                MyCart.getInstance().updateQuantity(quantity, foodTruckItem.getItemId(), false);
            }
        });

        holder.removeQuantity.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int quantity = foodTruckItem.getItemQuantityOrdered();
                quantity -= 1;
                if (quantity == 0) {
                    MyCart.getInstance().removeItem(foodTruckItem.getItemId(), false);
                    holder.addLayout.setVisibility(View.INVISIBLE);
                    holder.addText.setVisibility(View.VISIBLE);
                    listener.showSnackBar(quantity, false, position);
                } else {
                    holder.quantityText.setText(String.valueOf(quantity));
                    MyCart.getInstance().updateQuantity(quantity, foodTruckItem.getItemId(), false);
                }
            }
        });
        setFontStyle(holder);
    }


    private void addItem(MyViewHolder holder, int position, FoodTruckItem foodTruckItem) {
        holder.addLayout.setVisibility(View.VISIBLE);
        holder.addText.setVisibility(View.INVISIBLE);
        foodTruckItem.setItemQuantityOrdered(1);
        holder.quantityText.setText(String.valueOf(1));
        MyCart.getInstance().addItem(foodTruckItem);
        MyCart.getInstance().setFoodTruckId(foodtruckInfoList.get(position).getFoodTruckId());
        listener.showSnackBar(MyCart.getInstance().getItemList(), true, position);

    }

    private void setFontStyle(MyViewHolder holder) {
        holder.itemName.setTypeface(Typeface.createFromAsset(mContext.getAssets(), Consts.montserrat_bold));
//        holder.itemTag.setTypeface(Typeface.createFromAsset(mContext.getAssets(), Consts.montserrat_bold));
        holder.foodPrice.setTypeface(Typeface.createFromAsset(mContext.getAssets(), Consts.montserrat_bold));
        holder.addText.setTypeface(Typeface.createFromAsset(mContext.getAssets(), Consts.montserrat_bold));
    }


    @Override
    public int getItemCount() {
        return foodTruckItemList.size();
    }
}

这里我编写了addConflictItem(),并使用notifyItemChanged ,但是它似乎没有调用onBindViewHolder,请问应用程序有遗漏的吗?


我有完全相同的问题。 我想知道这是否与线程有关。 你最终解决了吗? - SudoPlz
4个回答

2

我曾经遇到过同样的问题,这个方法对我有用。只需在你的recyclerview声明中添加这些行,参见此答案

DefaultItemAnimator animator = new DefaultItemAnimator() {
    @Override
    public boolean canReuseUpdatedViewHolder(RecyclerView.ViewHolder viewHolder) {
        return true;
    }
}; 
mRecyclerView.setItemAnimator(animator);

在哪里放置这段代码? - WISHY
在 'onCreate()' 中,在 'recyclerView.setAdapter(adapter);' 之后。 - user9593218

0

根据我的经验,在onBindViewHolder中使用setOnClickListener不是一个好主意。

    public class PopularItemsAdapter extends RecyclerView.Adapter<PopularItemsAdapter.MyViewHolder>
        implements MyCartListener {

    private Context mContext;
    private List<FoodTruckItem> foodTruckItemList;
    private boolean isClickable = false;
    private OnItemClickListener listener;
    private List<FoodtruckInfo> foodtruckInfoList = new ArrayList<>();
    private List<FoodTruckItem> sessionItem = new ArrayList<>();
    private boolean isConflictResolved = false;
    public int position = -1;


    @Override
    public void itemUpdated(int quantity, String itemId) {
        for (int i = 0; i < foodTruckItemList.size(); i++) {
            if (itemId.equals(foodTruckItemList.get(i).getItemId())) {
                foodTruckItemList.get(i).setItemQuantityOrdered(quantity);
                //                notifyDataSetChanged();
            }
        }
    }

    @Override
    public void itemRemoved(String itemId) {
        for (int j = 0; j < foodTruckItemList.size(); j++) {
            if (itemId.equals(foodTruckItemList.get(j).getItemId())) {
                foodTruckItemList.remove(j);
                //                notifyDataSetChanged();
            }
        }
    }

    public void addConflictItem(int position) {
        isConflictResolved = true;
        notifyItemChanged(position);
    }

    public interface OnItemClickListener {
        void onItemClick(FoodTruckItem foodTruckItem, FoodtruckInfo foodtruckInfo);

        void showSnackBar(int items, boolean added, int position);

        void showRestaurentClosed();

        void showWarningDialog(int position);
    }


    public void addFoodInfo(List<FoodtruckInfo> foodtruckInfos) {
        foodtruckInfoList.addAll(foodtruckInfos);
    }


    public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView itemName, foodPrice, addText, quantityText, addQuantity, removeQuantity;
        public ImageView itemImage, itemTag;
        public LinearLayout addLayout;
        MyViewHolder holder;

        public MyViewHolder(View view) {
            super(view);
            itemTag = (ImageView) view.findViewById(R.id.itemTag);
            itemImage = (ImageView) view.findViewById(R.id.itemImage);
            itemName = (TextView) view.findViewById(R.id.itemName);
            foodPrice = (TextView) view.findViewById(R.id.foodPrice);
            addText = (TextView) view.findViewById(R.id.addText);
            addLayout = (LinearLayout) view.findViewById(R.id.addLayout);
            quantityText = (TextView) view.findViewById(R.id.quantityText);
            addQuantity = (TextView) view.findViewById(R.id.addQuantity);
            removeQuantity = (TextView) view.findViewById(R.id.removeQuantity);
            holder = this;
            view.setOnClickListener(this);
            addText.setOnClickListener(new View.OnClickListener() {
                FoodtruckInfo info = new FoodtruckInfo();

                @Override
                public void onClick(View v) {
                    int position = getAdapterPosition;
                    for (int l = 0; l < foodtruckInfoList.size(); l++) {
                        if (foodtruckInfoList.get(l).getItemId().equals(foodTruckItem.getItemId())) {
                            if (foodtruckInfoList.get(l).getOrderStatus() == 0) {
                                isClickable = true;
                            } else {
                                isClickable = false;
                            }
                        }
                    }
                    if (isClickable) {
                        String foodTruckId = null;
                        if (MyCart.getInstance().getFoodTruckId() != null) {
                            foodTruckId = MyCart.getInstance().getFoodTruckId();
                            if (!foodTruckId.equals(foodtruckInfoList.get(position).getFoodTruckId())) {
                                listener.showWarningDialog(position);
                            } else {
                                addItem(holder, position, foodTruckItem);
                            }
                        } else {
                            isConflictResolved = false;
                            addItem(holder, position, foodTruckItem);
                        }
                    } else {
                        listener.showRestaurentClosed();
                    }

                    if (isConflictResolved) {
                        isConflictResolved = false;
                        addItem(holder, position, foodTruckItem);
                    }
                }
            });
            removeQuantity.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = getAdapterPosition;
                    int quantity = foodTruckItem.getItemQuantityOrdered();
                    quantity -= 1;
                    if (quantity == 0) {
                        MyCart.getInstance().removeItem(foodTruckItem.getItemId(), false);
                        holder.addLayout.setVisibility(View.INVISIBLE);
                        holder.addText.setVisibility(View.VISIBLE);
                        listener.showSnackBar(quantity, false, position);
                    } else {
                        holder.quantityText.setText(String.valueOf(quantity));
                        MyCart.getInstance().updateQuantity(quantity, foodTruckItem.getItemId(), false);
                    }
                }
            });
            addQuantity.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int position = getAdapterPosition;
                    int quantity = foodTruckItem.getItemQuantityOrdered();
                    quantity += 1;
                    holder.quantityText.setText(String.valueOf(quantity));
                    MyCart.getInstance().updateQuantity(quantity, foodTruckItem.getItemId(), false);
                }
            });
        }

        @Override
        public void onClick(View view) {
            FoodtruckInfo foodtruckInfo = new FoodtruckInfo();
            //passing the clicked position to the parent class
            for (FoodtruckInfo info : foodtruckInfoList) {
                if (info.getItemId().equals(foodTruckItemList.get(getAdapterPosition()).getItemId())) {
                    foodtruckInfo = info;
                }
            }
            listener.onItemClick(foodTruckItemList.get(getAdapterPosition()), foodtruckInfo);
        }
    }


    public PopularItemsAdapter(Context mContext, List<FoodTruckItem> foodTruckItemList, OnItemClickListener listener) {
        this.mContext = mContext;
        this.foodTruckItemList = foodTruckItemList;
        this.listener = listener;
        MyCart.getInstance().addListener(this);
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.card_view_popular_items, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
        final FoodTruckItem foodTruckItem = foodTruckItemList.get(position);
        if (SessionManager.get(mContext).getFoodTruckItemList() != null) {
            sessionItem = SessionManager.get(mContext).getFoodTruckItemList();
            for (FoodTruckItem item : sessionItem) {
                if (item.getItemId().equals(foodTruckItem.getItemId())) {
                    //                    holder.itemTag.setText("MY FAVOURITE");
                    holder.itemTag.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.ic_favorite));
                }
            }
        }

        holder.itemName.setText(foodTruckItem.getItemName());
        //      holder.itemTag.setText(foodTruckItem.getSpecialTag());
        holder.foodPrice.setText("$" + String.valueOf(foodTruckItem.getItemPrice()));
        Picasso.Builder builder = new Picasso.Builder(mContext);
        builder.listener(new Picasso.Listener() {
            @Override
            public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
                exception.printStackTrace();
            }
        });
        if (!TextUtils.isEmpty(foodTruckItem.getItemImg())) {
            builder.build().load(foodTruckItem.getItemImg()).into(holder.itemImage);
        }

        setFontStyle(holder);
    }


    private void addItem(MyViewHolder holder, int position, FoodTruckItem foodTruckItem) {
        holder.addLayout.setVisibility(View.VISIBLE);
        holder.addText.setVisibility(View.INVISIBLE);
        foodTruckItem.setItemQuantityOrdered(1);
        holder.quantityText.setText(String.valueOf(1));
        MyCart.getInstance().addItem(foodTruckItem);
        MyCart.getInstance().setFoodTruckId(foodtruckInfoList.get(position).getFoodTruckId());
        listener.showSnackBar(MyCart.getInstance().getItemList(), true, position);

    }

    private void setFontStyle(MyViewHolder holder) {
        holder.itemName.setTypeface(Typeface.createFromAsset(mContext.getAssets(), Consts.montserrat_bold));
        //        holder.itemTag.setTypeface(Typeface.createFromAsset(mContext.getAssets(), Consts.montserrat_bold));
        holder.foodPrice.setTypeface(Typeface.createFromAsset(mContext.getAssets(), Consts.montserrat_bold));
        holder.addText.setTypeface(Typeface.createFromAsset(mContext.getAssets(), Consts.montserrat_bold));
    }


    @Override
    public int getItemCount() {
        return foodTruckItemList.size();
    }
}

0
这对我来说发生的原因是因为我在下载线程中调用了notifyItemChanged。从UI线程调用notifyItemChanged解决了这个问题。
final int finalI = i;
activity.runOnUiThread(() -> {
    notifyItemChanged(finalI);
});

-10
只需调用notifyDataSetChanged(),RecycleView就会刷新。

但是,那么我该如何告诉recyclerview关于特定位置的项目呢? - Mrugesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接