Home > OS >  How to Remove an item from recyclerview after recyclerview item's countdown timer expires?
How to Remove an item from recyclerview after recyclerview item's countdown timer expires?

Time:10-22

I am making some kind of Sale event app . For that i require a Recyclerview with each item having a countdown timer in it. Each items has countdown and it says "Sale begins in XX hr: YY min" And when the countdown of the item expires , the item should go down to the bottom of Recyclerview.

I have made a countdown timer inside onbindviewholder but i am getting error when the timer expires . Please someone help me overcome this... This is what is required img

The expiry time of each item is coming from Firestore database .

I am doing this in my onbindViewholder... String remTime;

@Override
public void onBindViewHolder(@NonNull Holder holder, int position) {
    ItemDet item = ItemArrayList.get(position);
    long timer = item.getCategoryTime().toDate().getTime();
    final long currentTime = System.currentTimeMillis();
    long expiryTime = timer - currentTime;

    if (holder.timer != null) {
        holder.timer.cancel();
    }

    holder.timer=new CountDownTimer(expiryTime, 1000) {
        public void onTick(long millisUntilFinished) {

            long seconds = millisUntilFinished / 1000;
            long minutes = seconds / 60;
            long hours = minutes / 60;
            long days = hours / 24;

            if(days==0){
                remTime= minutes % 60   "m:"   seconds % 60 "s";
            }
            if(days<1 && hours>0 && minutes>0 && seconds>0){
                remTime= hours % 24   "h:"  minutes % 60   "m";
            }
            if(days<1 && hours<1 && minutes>0 && seconds>0){
                remTime= minutes % 60   "m:"  seconds % 60 "s";
            }
            if(days<1 && hours<1 && minutes<1 && seconds>0){
                remTime= seconds % 60 "s";
            }
            if (days>0){
                remTime= days "d, "  hours % 24   "h";
            }
            holder.item_time_h.setText(remTime); 
        }

        public void onFinish() {
            holder.itemView.setEnabled(false);
            holder.item_time_h.setText("Time up!");

            ItemArrayList.remove(holder.adapterPosition());
            notifyItemRemoved(holder.adapterPosition());
            notifyItemRangeChanged(holder.adapterPosition(), ItemArrayList.size());
             
            //Here after timer finish i want to remove the item from the top and put it on bottom
            }

Please help me in this, i am stuck since 2 weeks

CodePudding user response:

This shouldn't be hard. When the timer ends, you should move the item to the end of the list and then notify the adapter about this.

public void onFinish() {
    holder.itemView.setEnabled(false);
    holder.item_time_h.setText("Time up!");

    int oldPosition = holder.adapterPosition();
    ItemDet item = ItemArrayList.remove(oldPosition);
    ItemArrayList.add(item);
    int newPosition = ItemArrayList.size() - 1;
    notifyItemMoved(oldPosition, newPosition);
}

Hope I didn't make mistakes. I didn't test the code. Try this. I'm hoping for some feedback from you.

UPDATE

Now I see that your expiryTime depends on the System's time and it's not a fixed value. As the time passes, some of your Counters will finish counting. In that exact moment when the Counter finishes to count, if you would recompute expiryTime, its value will be 0. When you exit the fragment and reenter it, the fragment will get recreated, the recyclerview will get recreated and the expiryTime will get recomputed and it will be a negative value. And because of that the Counter's onFinish method will be called right away, when the recycler's layout is being created. A quick fix could be that to not start the timer if expiryTime is negative. For the moment I think you could do this:

final long currentTime = System.currentTimeMillis();
long expiryTime = timer - currentTime;

//ADD THIS HERE
if(expiryTime <= 0) {
    return;
}

if (holder.timer != null) {
    holder.timer.cancel();
}
  • Related