Как удалить элемент из recyclerView в android

в моем приложении я должен использовать recyclerView и удалить некоторые элементы.
Я хочу удалить некоторые элементы из recyclerview и для этого я пишу ниже код адаптер :

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private Context context;
    private List<TvTonightResult> model;

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

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_tv_tonight, parent, false);

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(MyAdapter.ViewHolder holder, final int position) {

        holder.tvTonightTitle.setText(Html.fromHtml(model.get(position).getName()));
        Glide.with(context)
                .load(model.get(position).getImageUrl())
                .placeholder(R.drawable.default_image)
                .override(600, 900)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .listener(new RequestListener<String, GlideDrawable>() {
                    @Override
                    public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(GlideDrawable resource, String model,
                                                   Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                        return false;
                    }
                })
                .into(holder.tvTonightImage);

        long time = 5 * 1000;
        holder.tvTonightTimeCounter.start(time);
        holder.tvTonightTimeCounter.setOnCountdownEndListener(new CountdownView.OnCountdownEndListener() {
            @Override
            public void onEnd(CountdownView cv) {
                removeItem(position);
            }
        });
    }

    @Override
    public int getItemCount() {
        return 4;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        private ImageView tvTonightImage, tvTonightChannel;
        private TextView tvTonightTitle, tvTonightDate;
        private CountdownView tvTonightTimeCounter;

        public ViewHolder(View itemView) {
            super(itemView);

            tvTonightImage = (ImageView) itemView.findViewById(R.id.row_tvTonightImage);
            tvTonightChannel = (ImageView) itemView.findViewById(R.id.row_tvTonightChannelImage);
            tvTonightTitle = (TextView) itemView.findViewById(R.id.row_tvTonightTitle);
            tvTonightTimeCounter = (CountdownView) itemView.findViewById(R.id.row_tvTonightTime);

        }
    }

    private void removeItem(int position) {
        model.remove(position);
        notifyItemRemoved(position);
        notifyItemRangeChanged(position, model.size());
    }
}

Я хочу, когда запустить этот код,удалить элемент :

holder.tvTonightTimeCounter.setOnCountdownEndListener(new CountdownView.OnCountdownEndListener() {
                @Override
                public void onEnd(CountdownView cv) {
                    removeItem(position);
                }
            });

но покажите мне этот :

FATAL EXCEPTION: main
Process: com.example.app, PID: 9711
java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
    at java.util.ArrayList.remove(ArrayList.java:477)
    at com.example.app.Adapters.TvTonightAdapter.removeItem(TvTonightAdapter.java:102)
    at com.example.app.Adapters.TvTonightAdapter.access0(MyAdapter.java:29)
    at com.example.app.Adapters.TvTonightAdapter.onEnd(MyAdapter.java:74)
    at com.example.app.Utils.Componenets.CountDownTimer.CountdownView.onFinish(CountdownView.java:129)
    at com.example.app.Utils.Componenets.CountDownTimer.CustomCountDownTimer.handleMessage(CustomCountDownTimer.java:74)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6247)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)

как я могу исправить эту ошибку и удалить элемент из recyclerview?

6 ответов


Я думаю, вы должны позвонить remove(holder.getAdapterPosition()) вместо remove(position) потому что, когда обратный отсчет держателя заканчивается, он, возможно, изменил свое положение.

предположим следующую ситуацию:

1º держатель - > 5 секунд обратный отсчет

2º держатель - > 10 секунд обратный отсчет

со второй держатель заканчивается после первого, через 10 секунд remove(1) будет вызываться, но, поскольку первый держатель уже удален, позиция второго держателя будет быть 0. Следовательно, он должен вызвать remove(0) вместо remove(1) (что приведет к IndexOutOfBoundsException).


просто попробовать ,

int newPosition = holder.getAdapterPosition();

в вашем методе removeItem () и положении repalce с newPosition.

например ,

  private void removeItem(int position) {
    int newPosition = holder.getAdapterPosition();
    model.remove(newPosition);
    notifyItemRemoved(newPosition);
    notifyItemRangeChanged(newPosition, model.size());
}

удалить элемент в Arraylist в Android

holder.mRemoveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                // Get the clicked item label
                String itemLabel = mDataSet.get(position);
                // Remove the item on remove/button click
                mDataSet.remove(position);
                notifyItemRemoved(position);
                notifyItemRangeChanged(position,mDataSet.size());
                // Show the removed item label`enter code here`
                Toast.makeText(mContext,"Removed : " + itemLabel,Toast.LENGTH_SHORT).show();

}

нет необходимости удалять элементы, если вы хотите отобразить только 4 элемента, просто измените метод подсчета, как показано ниже

 @Override
    public int getItemCount() {
        return (model.size()>4)?4:model.size();
    }

Если вы хотите отобразить только четыре элемента, если их больше четырех, и точное количество элементов, если их меньше четырех. Затем, вы можете использовать это:

@Override
public int getItemCount() {
    int count = 0;
    if (model != null && model.size() > 0) {
        int listSize = model.size();
        if (listSize > 4) {
            count = 4;
        } else {
            count = listSize;
        }
    }
    return count;
}

//////// set the position ////////

holder.tvTonightTimeCounter.setTag(position);

//////// remove item from recyclerview and arraylist ///////

holder.tvTonightTimeCounter.setOnCountdownEndListener(new CountdownView.OnCountdownEndListener() {
                    @Override
                    public void onEnd(CountdownView cv) {
                    int positionToRemove = (int)view.getTag(); //get the position of view to delete stored in the tag
                    model.remove(positionToRemove);
                    notifyDataSetChanged();
                    }
                });