私のアプリケーションでは、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
からアイテムを削除するにはどうすればよいですか?
remove(holder.getAdapterPosition())
の代わりにremove(position)
を呼び出すべきだと思います。なぜなら、ホルダーのカウントダウンが終了すると、その位置が変わったかもしれないからです。
次の状況を想定します。
1ºホルダー-> 5秒のカウントダウン
2ºホルダー-> 10秒のカウントダウン
2番目のホルダーは最初のホルダーの後に終了するため、10秒後にremove(1)
が呼び出されますが、最初のホルダーが既に削除されているため、2番目のホルダーの位置は0になります。したがって、remove(0)
の代わりにremove(1)
IndexOutOfBoundsException
)。
ちょうど試して 、
int newPosition = holder.getAdapterPosition();
removeItem()メソッドで、位置を新しい位置に置き換えます。
お気に入り 、
private void removeItem(int position) {
int newPosition = holder.getAdapterPosition();
model.remove(newPosition);
notifyItemRemoved(newPosition);
notifyItemRangeChanged(newPosition, model.size());
}
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();
}
以下のようにgetメソッドを変更するだけで4つのアイテムを表示する場合は、アイテムを削除する必要はありません。
@Override
public int getItemCount() {
return (model.size()>4)?4:model.size();
}
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;
}
//////// 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();
}
});