Reputation: 143
In my application I should use recyclerView and remove some items.
I want remove some items from recyclerview
and for this I write below code in 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());
}
}
I want when run this code, remove item :
holder.tvTonightTimeCounter.setOnCountdownEndListener(new CountdownView.OnCountdownEndListener() {
@Override
public void onEnd(CountdownView cv) {
removeItem(position);
}
});
But show me this 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)
How can I fix this error and remove item from recyclerview
?
Upvotes: 14
Views: 37371
Reputation: 3100
just try ,
int actualPosition = holder.getAdapterPosition();
in your removeItem()
method and replace position with actualPosition
.
like ,
private void removeItem(int position) {
int actualPosition = holder.getAdapterPosition();
model.remove(actualPosition);
notifyItemRemoved(actualPosition);
notifyItemRangeChanged(actualPosition, model.size());
}
Upvotes: 20
Reputation: 1030
//////// 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();
}
});
Upvotes: -1
Reputation: 3815
If you want to display only four item if there are more than four item and exact number of item if there are less than four item. Then, you can use this:
@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;
}
Upvotes: 0
Reputation: 2852
There is no need to remove items if you want to display just 4 items just change get count method as below
@Override
public int getItemCount() {
return (model.size()>4)?4:model.size();
}
Upvotes: 0
Reputation: 341
I think you should call remove(holder.getAdapterPosition())
instead of remove(position)
because, when the holder's countdown finishes, it might have changed its position.
Suppose the following situation:
1º holder -> 5 seconds countdown
2º holder -> 10 seconds countdown
Since the second holder finishes after the first one, after 10 seconds, remove(1)
will be called but, since the first holder has already been removed, the second holder's position will be 0. Hence, it should call remove(0)
instead of remove(1)
(which will cause an IndexOutOfBoundsException
).
Upvotes: 13