web-dev-qa-db-ja.com

androidでrecyclerViewからアイテムを削除する方法

私のアプリケーションでは、recyclerViewを使用していくつかのアイテムを削除する必要があります。
recyclerviewからいくつかのアイテムを削除したいので、以下のコードをAdapterで記述します。

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());
    }
}

このコードを実行するときに、remove itemが必要です:

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

しかし、これを見せてくださいerror

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.access$300(MyAdapter.Java:29)
    at com.example.app.Adapters.TvTonightAdapter$2.onEnd(MyAdapter.Java:74)
    at com.example.app.Utils.Componenets.CountDownTimer.CountdownView$1.onFinish(CountdownView.Java:129)
    at com.example.app.Utils.Componenets.CountDownTimer.CustomCountDownTimer$1.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からアイテムを削除するにはどうすればよいですか?

8
Kol

remove(holder.getAdapterPosition())の代わりにremove(position)を呼び出すべきだと思います。なぜなら、ホルダーのカウントダウンが終了すると、その位置が変わったかもしれないからです。

次の状況を想定します。

1ºホルダー-> 5秒のカウントダウン

2ºホルダー-> 10秒のカウントダウン

2番目のホルダーは最初のホルダーの後に終了するため、10秒後にremove(1)が呼び出されますが、最初のホルダーが既に削除されているため、2番目のホルダーの位置は0になります。したがって、remove(0)の代わりにremove(1)IndexOutOfBoundsException)。

6
Gabriel Costa

ちょうど試して 、

int newPosition = holder.getAdapterPosition();

removeItem()メソッドで、位置を新しい位置に置き換えます。

お気に入り 、

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

AndroidのArraylistのアイテムを削除する

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();

}
1

以下のようにgetメソッドを変更するだけで4つのアイテムを表示する場合は、アイテムを削除する必要はありません。

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

4つ以上のアイテムがある場合は4つのアイテムのみを表示し、4つ未満のアイテムがある場合はアイテムの正確な数を表示する場合。次に、これを使用できます。

@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;
}
0
Satan Pandeya
//////// 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();
                    }
                });
0
roshan posakya