using notifyItemRemoved or notifyDataSetChanged with RecyclerView in Android

后端 未结 8 2136
忘掉有多难
忘掉有多难 2020-12-04 17:28

I am creating a list of cards to display using the RecyclerView, where each card has a button to remove that card from the list.

When i use notifyItemRemoved

相关标签:
8条回答
  • 2020-12-04 17:54
    **my solution looks like this**
    
    this way is unnecessary to use the heavy method:
     //notifyItemRangeChanged(xx,xx)
    
    /**
     * 
     * recyclerView的item中的某一个view,获取其最外层的viewParent,也就是item对应的layout在adapter中的position
     *
     * @param recyclerView
     * @param view:can be the deep one inside the item,or the item itself .
     * @return
     */
    public static int getParentAdapterPosition(RecyclerView recyclerView, View view, int parentId) {
        if (view.getId() == parentId)
            return recyclerView.getChildAdapterPosition(view);
        View viewGroup = (View) view.getParent();
        if (viewGroup != null && viewGroup.getId() == parentId) {
            return recyclerView.getChildAdapterPosition(viewGroup);
        }
        //recursion
        return getParentAdapterPosition(recyclerView, viewGroup, parentId);
    }
    
    
    
    
    //wherever you set the clickListener .
    holder.setOnClickListener(R.id.rLayout_device_item, deviceItemClickListener);
    holder.setOnLongClickListener(R.id.rLayout_device_item, deviceItemLongClickListener);
    
    
    @Override
    public boolean onLongClick(View v) {
        final int position = ViewUtils.getParentAdapterPosition(rVDevicesList, v, R.id.rLayout_device_item);
        return true;
    }
    
    0 讨论(0)
  • 2020-12-04 17:55

    You should add remove listener in ViewHolder class

     button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                       onCancel(getAdapterPosition());
    
                }
            });
    
      private void onCancel(int position) {
            if (position >= issues.size())
                return;
            issues.remove(position);
            notifyItemRemoved(position);
        }
    
    0 讨论(0)
  • 2020-12-04 17:58

    my mistake , notifyItemChanged(position) is helpless,the item of position can be removed ,and the item of position+1 is fine,but the items start from position+2,you will get an Exception, please use notifyItemRangeChanged(position,getItemCount()); after notifyItemRemoved(position);

    like this:

    public void removeData(int position) {
        yourdatalist.remove(position);
        notifyItemRemoved(position);
        notifyItemRangeChanged(position,getItemCount());
    }
    
    0 讨论(0)
  • 2020-12-04 17:58

    As @pskink suggested it was supposed to be (index+1) in my case with notifyItemRemoved(index+1), probably because i am reserving the top index i.e. position=0 for a header.

    0 讨论(0)
  • 2020-12-04 18:04

    In my case I use Content Provider and a Custom RecyclerView Adapter with Cursor. This line of code is where you notify:

    getContext().getContentResolver().notifyChange(uri, null);
    

    Assuming In your recyclerView adapter (Delete Button):

    Uri currentUri = ContentUris.withAppendedId(DatabaseContract.ToDoEntry.CONTENT_URI_TODO, id);
    int rowsDeleted = mContext.getContentResolver().delete(currentUri, null, null);
    if (rowsDeleted == 0) {
        Log.d(TAG, "onClick: Delete failed");
    } else {
        Log.d(TAG, "onClick: Delete Successful");
    }
    

    And in your Database Provider:

    case TODO_ID:
    selection = DatabaseContract.ToDoEntry._ID + "=?";
    selectionArgs = new String[] {String.valueOf(ContentUris.parseId(uri))};
    rowsDeleted = database.delete(DatabaseContract.ToDoEntry.TODO_TABLE_NAME, selection, selectionArgs);
    if (rowsDeleted != 0){
        getContext().getContentResolver().notifyChange(uri, null);
    }
    return rowsDeleted;
    
    0 讨论(0)
  • 2020-12-04 18:07

    Use notifyItemRangeChanged(position, getItemCount()); after notifyItemRemoved(position);
    You don't need to use index, just use position. See code below.

    private List<DetectedIssue> issues = new ArrayList<DetectedIssue>();
    
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        if(position >0){
            RiskViewHolder riskHolder = (RiskViewHolder)holder;
    
            riskHolder.button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    try {
                        issues.remove(position);
                        notifyItemRemoved(position);
                        //this line below gives you the animation and also updates the
                        //list items after the deleted item
                        notifyItemRangeChanged(position, getItemCount());
    
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
    
    @Override
    public int getItemCount() {
        return issues.size();
    }
    
    0 讨论(0)
提交回复
热议问题