【问题标题】:last item get deleted when clicked on the first item in recyclerview adapter单击 recyclerview 适配器中的第一项时,最后一项被删除
【发布时间】:2018-10-10 03:13:19
【问题描述】:

我有一个 RecyclerView.inflated 从对象的 ArrayList。我在项目上添加了一个删除按钮,我想删除单击的项目。但是当点击而不是点击的项目时,最后一个项目被删除。无论点击什么项目,最后一个项目都会被删除。有谁知道为什么会这样?

适配器:

    public class NotificationAdapter extends RecyclerView.Adapter<NotificationAdapter.NotificationViewHolder> {

    private ArrayList<NotificationItem> mNotificationList;
    private onItemClickListner mListner;

    private Context myContext;
    private int layoutResID;

   public interface onItemClickListner{
     void onItemClick(int position);
     void onDeleteClick(int position);
    }

//    public void setOnItemClickListner(onItemClickListner listner){
//       mListner=listner;
//    }

    //NOTIFICATION HOLDER
    public static class NotificationViewHolder extends RecyclerView.ViewHolder{
        public TextView mNotificationTextView;
        public RelativeLayout mNotificaionHolderLayout;
        public ImageView imageDelete;
        onItemClickListner listner;


        public NotificationViewHolder(View itemView,final onItemClickListner listner) {
            super(itemView);
            mNotificationTextView=itemView.findViewById(R.id.NotificationTextView);
            mNotificaionHolderLayout=itemView.findViewById(R.id.notification__item_container);
            imageDelete=itemView.findViewById(R.id.notification_delete_image);
            this.listner=listner;


            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                   if (listner!=null){
                       int position=getAdapterPosition();
                       if (position!=RecyclerView.NO_POSITION){
                           listner.onItemClick(position);
                       }
                   }
                }
            });

            imageDelete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (listner!=null){
                        int position=getAdapterPosition();
                        if (position!=RecyclerView.NO_POSITION){
                            listner.onDeleteClick(position);
                        }
                    }
                }
            });
        }
    }//NOTIFICATION HOLDER

    public NotificationAdapter(Context context, int resource, ArrayList<NotificationItem> notificationList,onItemClickListner listner){
        myContext=context;
        this.layoutResID=resource;
        mNotificationList=notificationList;
        this.mListner=listner;
    }


    @Override
    public NotificationViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v=LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_notificationitem,parent,false);
        NotificationViewHolder evh=new NotificationViewHolder(v,mListner);
        return evh;
    }

    @Override
    public void onBindViewHolder(NotificationViewHolder holder, int position) {
        NotificationItem currentItem=mNotificationList.get(position);
        holder.mNotificaionHolderLayout.setBackgroundColor(Color.parseColor(Getcolor(position)));
        holder.mNotificationTextView.setText(currentItem.getNotifi_Name());
    }

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

    private String Getcolor(int position)
    {
        String clr;

        switch (position)
        {
            case 0:
                clr="#FF9966";
                break;

            case 1:
                clr="#009900";
                break;

            case 2:
                clr="#006699";
                break;

            case 3:
                clr="#751947";
                break;
            case 4:
                clr="#FF9966";
                break;

            case 5:
                clr="#009900";
                break;

            case 6:
                clr="#006699";
                break;

            case 7:
                clr="#751947";
                break;


            default:
                clr="#FFA500";
                break;
        }
        return clr;
    }

}

家庭活动:

我已经在 home 类中实现了 NotificationAdapter 并覆盖了函数。并将适配器设置为回收器视图。

    @Override
public void onItemClick(int position) {
    FlashMessage("SOMETHING");
    nfAdapter.notifyDataSetChanged();
    nfAdapter.notifyItemRemoved(position);
    nfAdapter.notifyItemRangeChanged(position,listNotifi.size());
}

@Override
public void onDeleteClick(int position) {
       FlashMessage("DELETED ON POSITION : " +position);
       listNotifi.remove(position);
       nfAdapter.notifyDataSetChanged();
       nfAdapter.notifyItemRemoved(position);
       nfAdapter.notifyItemRangeChanged(position,listNotifi.size());

}

【问题讨论】:

    标签: android android-recyclerview


    【解决方案1】:

    因为 RecyclerView 适配器设置为在屏幕外重用视图,所以在 ViewHolder 声明中声明侦听器是不好的做法。

    如果您的 onClickListeners 依赖于项目在整个列表中的位置,您将想知道该位置,而不是适配器列表本身中的位置。 (这就是适配器的重点,它重用了它的视图来存储内存。最好只保留持有者类以将公共变量声明为 xml 视图 id。)只需移动这些行:

    itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                   if (listner!=null){
                       int position=getAdapterPosition();
                       if (position!=RecyclerView.NO_POSITION){
                           listner.onItemClick(position);
                       }
                   }
                }
            });
    
            imageDelete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (listner!=null){
                        int position=getAdapterPosition();
                        if (position!=RecyclerView.NO_POSITION){
                            listner.onDeleteClick(position);
                        }
                    }
                }
            });
    

    到你的 onBindViewHolder,像这样:

    @Override
    public void onBindViewHolder(NotificationViewHolder holder, int position) {
        NotificationItem currentItem=mNotificationList.get(position);
    
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                       //listener stuff using position from onBindViewHolder input
            }
        });
    
        holder.imageDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    //listener stuff using position from onBindViewHolder input
            }
        });
    
        holder.mNotificaionHolderLayout.setBackgroundColor(Color.parseColor(Getcolor(position)));
        holder.mNotificationTextView.setText(currentItem.getNotifi_Name());
    
    
    }
    

    【讨论】:

    • 是的。有效。在 Home 活动或 Holder 中使用侦听器效果不佳。
    • 我认为这是最简单的方法。也许在适配器中声明监听器和在活动中声明回调方法稍微简洁一些,但是这样更不容易出错。我认为唯一的问题是更大的 RV 列表的内存,因为所有的听众都留下了?老实说,如果不重新阅读一堆开发参考资料,我现在不确定这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多