【问题标题】:RecyclerView does not update after removing an item [duplicate]删除项目后RecyclerView不更新[重复]
【发布时间】:2017-07-31 10:24:10
【问题描述】:

我在片段底部有一个RecyclerView 水平图像滑块。片段的顶部显示了一些细节。一旦用户单击底部的图像,想法就是从图像滑块中删除该图像并在片段中显示其信息。现在信息显示了,但图像并未从RecyclerView 中删除。这是我在最外层布局的Onclick 中编码的内容。我已经尝试了所有我能找到的相关答案,但没有任何效果。它们都在代码中。请让我知道我做错了什么或缺少什么。

holder.itemRowRelativeLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (isFiltering) {
                mItemList.clear();
                mItemList.addAll(mOriginalItemList);
                mItemList.remove(position);// At this point mItemList holds the correct. That is all the images but not the one that was clicked. 

                notifyItemRemoved(position); //solution 1
                notifyItemRangeRemoved(position, getItemCount()); // solution 2
                notifyItemRangeRemoved(0, getItemCount()); // solution 3
                notifyDataSetChanged();//solution 4
            }
        }
    });

适配器的完整代码

public class ImageGallery16X9Adapter<T extends GalleryItem> extends RecyclerView.Adapter<ImageGallery16X9Adapter.GalleryItemViewHolder> {

public enum GalleryMode {
    All_SAME,
    FIRST_DIFFERENT
}

private Context mContext;
private BasePresenter mPresenter;
private List<T> mItemList;
private List<T> mOriginalItemList;
private GalleryItem mFirstItem;
private GalleryMode mGalleryMode;
private int deviceWidth, itemWidth, marginSingle, marginDouble;
private boolean isFiltering;

public ImageGallery16X9Adapter(Context context, BasePresenter presenter, GalleryMode galleryMode, List<T> itemList, GalleryItem firstItem, boolean isFiltering) {
    mContext = context;
    mPresenter = presenter;
    mGalleryMode = galleryMode;
    mItemList = new ArrayList<>(itemList);
    mOriginalItemList = new ArrayList<>(itemList);
    mFirstItem = firstItem;
    deviceWidth = CommonUtils.getDeviceWidth((Activity) mContext);
    itemWidth = (int) (deviceWidth * 0.9);
    marginDouble = (int) (deviceWidth * 0.05);
    marginSingle = (int) (deviceWidth * 0.025);
    this.isFiltering = isFiltering;
}

@Override
public GalleryItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    return new GalleryItemViewHolder(LayoutInflater.from(parent.getContext()).
            inflate(R.layout.row_image_gallery_16x9_item, parent, false));
}

@Override
public void onBindViewHolder(GalleryItemViewHolder holder, final int position) {
    RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) holder.itemRowRelativeLayout.getLayoutParams();
    RelativeLayout.LayoutParams rlParams = (RelativeLayout.LayoutParams) holder.itemImageView.getLayoutParams();
    layoutParams.width = itemWidth;
    rlParams.height = (int) (layoutParams.width * Constant.HEIGHT_FACTOR_16X9);

    if (position == 0) {
        layoutParams.leftMargin = marginDouble;
        layoutParams.rightMargin = 0;
        if (mGalleryMode == GalleryMode.FIRST_DIFFERENT) {
            holder.itemTitle.setVisibility(View.VISIBLE);
            holder.itemTitle.setText(mFirstItem.getItemTitle());
            if (mFirstItem.getItemImage() != null) {
                Picasso.with(MyApplication.getAppContext()).load(mFirstItem.getItemImage()).fit().placeholder(R.drawable.error_image).error(R.drawable.error_image).into(holder.itemImageView);
            } else {
                Picasso.with(MyApplication.getAppContext()).load(R.drawable.error_image).placeholder(R.drawable.error_image).error(R.drawable.error_image).fit().into(holder.itemImageView);
            }
            holder.itemDescription.setText(mFirstItem.getItemDescription());
        }
    } else {
        if (mGalleryMode == GalleryMode.FIRST_DIFFERENT) {
            if (position == mItemList.size()) {
                layoutParams.rightMargin = marginDouble;
            } else {
                layoutParams.rightMargin = 0;
            }
        } else {
            if (position == mItemList.size() - 1) {
                layoutParams.rightMargin = marginDouble;
            } else {
                layoutParams.rightMargin = 0;
            }
        }
        layoutParams.leftMargin = marginSingle;
    }

    int itemPosition = position;
    if (mGalleryMode == GalleryMode.FIRST_DIFFERENT && position > 0) {
        itemPosition = position - 1;
        T item = mItemList.get(itemPosition);
        holder.itemTitle.setVisibility(View.GONE);
        holder.itemDescription.setText(item.getItemDescription());
        Picasso.with(mContext).load(item.getItemImage()).fit().placeholder(R.drawable.error_image).error(R.drawable.error_image).into(holder.itemImageView);

    } else if (mGalleryMode == GalleryMode.All_SAME) {
        T item = mItemList.get(itemPosition);
        holder.itemTitle.setVisibility(View.GONE);
        holder.itemDescription.setText(item.getItemDescription());
        Picasso.with(mContext).load(item.getItemImage()).fit().placeholder(R.drawable.error_image).error(R.drawable.error_image).into(holder.itemImageView);
    }

    holder.itemRowRelativeLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mGalleryMode == GalleryMode.FIRST_DIFFERENT) {
                if (position == 0) {
                    mPresenter.onItemClicked(mFirstItem);
                } else {
                    mPresenter.onItemClicked(mItemList.get(position - 1));
                }
            } else {
                mPresenter.onItemClicked(mItemList.get(position));
                if (isFiltering) {
                    mItemList.clear();
                    mItemList.addAll(mOriginalItemList);
                    mItemList.remove(position);

                    notifyItemRemoved(position); //solution 1
                    notifyItemRangeRemoved(position, getItemCount()); // solution 2
                    notifyItemRangeRemoved(0, getItemCount()); // solution 3
                    notifyDataSetChanged();//solution 4
                }
            }
        }
    });
}

@Override
public int getItemCount() {
    if (mGalleryMode == GalleryMode.FIRST_DIFFERENT)
        return mItemList.size() + 1;
    else
        return mItemList.size();
}


static class GalleryItemViewHolder extends RecyclerView.ViewHolder {
    private final TextView itemDescription, itemTitle;
    private final ImageView itemImageView, itemFavoriteImageView;
    private final RelativeLayout itemRowRelativeLayout;

    public GalleryItemViewHolder(View itemView) {
        super(itemView);
        itemRowRelativeLayout = (RelativeLayout) itemView.findViewById(R.id.rl_gallery_item_row);
        itemImageView = (ImageView) itemView.findViewById(R.id.img_gallery_item);
        itemFavoriteImageView = (ImageView) itemView.findViewById(R.id.img_gallery_item_favorite);
        itemTitle = (TextView) itemView.findViewById(R.id.txt_gallery_item_name);
        itemDescription = (TextView) itemView.findViewById(R.id.txt_gallery_item_description);
    }
}

}

【问题讨论】:

  • 显示完整的适配器代码,
  • 点击最外层时请检查是否调用了该方法。 (使用日志检查)
  • @MohdSaquib 我已经看过了。对我没用。
  • @Jordan 是的,我确实尝试过。我的清单有正确的项目集。只有 recyclerview 不会更新和反映新项目。

标签: android android-fragments android-adapter android-recyclerview


【解决方案1】:

你需要使用这 3 行来使它工作

mItemList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mItemList.size());

【讨论】:

  • 这有一些问题,单击按钮我正在更改其背景可绘制对象(绿色 -> 红色),然后执行这三行。但发生的情况是,当我滚动旧的已删除布局时,某些地方开始显示。 :(
  • 您是否尝试过覆盖这两种方法?覆盖 public int getItemViewType(int position) { return position; } 覆盖 public long getItemId(int position) { return position; }
  • @Jay 这种行为是因为 recycler-view 重用视图,并且当视图不再在内存中时调用 onBindView Holder,因此您需要为每一行设置您偏好的颜色。
  • @jaydeeppipaliya 是否有任何类似的代码可用于 notifyItemMoved(fromPosition, to Position) ?
  • 您好我有一个问题,在删除一个项目后,我所有的下一个编辑文本都被设置为空,从 recyclerview 删除另一个项目后,我再次获取所有数据。我正在使用这 3 行来删除项目。
【解决方案2】:
private void removerecyclerItem(DraftStoriesPojo list) {
        int current_position = allStoriesPojoList.indexOf(list);
        allStoriesPojoList.remove(current_position);
        notifyItemRemoved(current_position);
        notifyItemRangeChanged (current_position, getItemCount());
    }

【讨论】:

    【解决方案3】:

    在您的自定义 RecylerView 中声明一个方法,如下所示

    public void DeleteData(int position){
    
            recordingItems.remove(position);
            notifyItemRemoved(position);
            notifyItemRangeChanged(position, recordingItems.size());
        }
    

    来自mainActivity的电话

    adapter.DeleteData(position);
    

    【讨论】:

      【解决方案4】:

      为了让您的代码正常工作,您需要按如下方式更改适配器构造函数的实现:

          public RecyclerViewAdapter(Context context, List<Model> model) {
          this.context = context;
          this.model = model;
      }
      

      然后在 onActivityResult 中这样做:

          @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
          super.onActivityResult(requestCode, resultCode, data);
          if (requestCode == 4) {
              listModel.clear();
              listModel.addAll(repository.consDataBase(context));
              recyclerViewAdapter.notifyDataSetChanged();
          }
      }
      

      【讨论】:

      • 哎哟!伤害
      【解决方案5】:

      那里不需要做那么多复杂的事情,只需删除并通知

      holder.itemRowRelativeLayout.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              if (isFiltering) {
                  mItemList.remove(position);
                  notifyItemRemoved(position);
              }
          }
      });
      

      【讨论】:

      • 我必须维护一个原始项目列表,因为我必须显示除单击的图像之外的所有其他图像。我已经尝试过这个解决方案。它在我的代码中提到。它对我不起作用。
      • 不用做mItemList.clear(),mItemList.addAll(mOriginalItemList)这些事情
      • 从主列表中删除后,我将如何获得完整的项目集。这就是为什么我要维护另一个包含所有项目的列表。这两条线有一个适当的理由在那里。请仔细阅读我在问题中提供的信息。
      • 您是否尝试过解决方案。您只删除了一项而不是整个列表,所以为什么需要再次清除并添加整个列表:/.
      • 我已经尝试了我发布的所有解决方案。我在帖子中提到了这一点。而且您无法理解这种情况。考虑用户第二次点击图像。这次我要将第一个点击的项目添加回列表,然后删除第二个点击的项目。所以我要删除所有项目并再次添加它们,然后删除第二个点击的项目。如果您仍然不明白,请尝试自己实现,而不是发表评论。
      【解决方案6】:

      只添加这两行

      mItemList.remove(position);
      notifyDataSetChanged();
      

      【讨论】:

      • notifyDataSetChanged 将打破所有 RecyclerView 概念
      【解决方案7】:

      您需要使用这些行来使其工作

      mItemList.remove(position);
      notifyDataSetChanged();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-17
        • 1970-01-01
        • 1970-01-01
        • 2018-09-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多