Skip to content Skip to sidebar Skip to footer

Removing Item From Recyclerview When Time Expired

I need to remove an item when time expired, partially i got output by referring this How to handle multiple countdown timers in ListView? After scrolled the list, some of the time

Solution 1:

You can achieve this by setting up the CountDownTimer which will trigger onTick() method every second. In onTick() method check if there are any objects those are expired? If you find any object remove them by calling notifyItemRemoved().

Here is the code of recycler view adapter:

private class RecyclerViewAdapter extends RecyclerView.Adapter { private ArrayList mData;

publicRecyclerViewAdapter(ArrayList<RowData> data) {
        mData = data;

        //find out the maximum time the timerlongmaxTime= System.currentTimeMillis();
        for (RowData item : mData) {
            maxTime = Math.max(maxTime, item.endTime);
        }

        //set the timer which will refresh the data every 1 second.newCountDownTimer(maxTime - System.currentTimeMillis(), 1000) {
            @OverridepublicvoidonTick(long l) {
                for (inti=0, dataLength = mData.size(); i < dataLength; i++) {
                    RowDataitem= mData.get(i);
                    item.timeRemaining -= 1000;
                }

                //remove the expired items
                Iterator<RowData> dataIterator = mData.iterator();
                while (dataIterator.hasNext()) {
                    RowDatard= dataIterator.next();
                    if (rd.timeRemaining <= 0) dataIterator.remove();
                }
                notifyDataSetChanged();
            }

            @OverridepublicvoidonFinish() {
                mData.clear();
                notifyDataSetChanged();
            }
        }.start();
    }

    @Overridepublic MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        returnnewMyViewHolder(LayoutInflater.from(MainActivity.this).inflate(android.R.layout.simple_list_item_2, parent, false));
    }

    @OverridepublicvoidonBindViewHolder(MyViewHolder holder, int position) {
        RowDatarowData= mData.get(position);
        holder.titleTv.setText(rowData.title);
        holder.remainingTimeTv.setText(millToMins(rowData.timeRemaining) + " mins remaining");
    }

    private String millToMins(long millisec) {
        return millisec / (60000) + ":" + (int) (millisec/1000) % (60);
    }

    @OverridepublicintgetItemCount() {
        return mData.size();
    }

    publicclassMyViewHolderextendsRecyclerView.ViewHolder {
        private TextView remainingTimeTv;
        private TextView titleTv;

        publicMyViewHolder(View itemView) {
            super(itemView);
            remainingTimeTv = (TextView) itemView.findViewById(android.R.id.text2);
            titleTv = (TextView) itemView.findViewById(android.R.id.text1);
        }
    }

}

P.S. : Here is the full code demo available on my GitHub account.

Solution 2:

The thing that you want is similar to filter on difference is that you want the item to be removed . I would suggest setting an Observer for all the timers in the list and whenever your timer crosses the schedule you have to update the observer , which will remove it form the list or arraylist of items that you have. Notify your data set that a change has occurred which will refresh your RecyclerView.

Solution 3:

You can have a periodic operation set-up that will remove items from RecyclerView adapter. Below is a crude example.

First, define the item class that represents list items:

import android.text.format.DateFormat;

publicclassTimedItem {
    private final long expireAt;
    private final String  name;

    publicTimedItem(String name, long expireAt) {
        this.name = name;
        this.expireAt = expireAt;
    }

    publicStringgetName() {
        return name;
    }

    publicStringgetDescription(){
        returnString.format("Expires at %s.", DateFormat.format("h:mm:ss a ddd, MMM, YYYY",this.expireAt));
    }

    publicbooleanisExpired(){
        returnSystem.currentTimeMillis() > this.expireAt;
    }
}

Since the items are to be displayed using RecyclerView, define a ViewHolder as well:

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;

publicclassTimedItemHolderextendsRecyclerView.ViewHolder {
    privatefinal TextView nameView;
    privatefinal TextView descView;
    publicTimedItemHolder(View itemView) {
        super(itemView);
        this.nameView = (TextView) itemView.findViewById(android.R.id.text1);
        this.descView = (TextView) itemView.findViewById(android.R.id.text2);
    }

    public TextView getNameView() {
        return nameView;
    }

    public TextView getDescView() {
        return descView;
    }
}

Now, to display items in RecycleView, we need to define an RecyclerView.Adapter. This will also handle item removal on expiry :

import android.os.Handler;
import android.os.Looper;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;


publicclassTimerAdapterextendsRecyclerView.Adapter<TimedItemHolder> {
    privatefinal List<TimedItem> items = newArrayList<>();
    privatefinalHandlerhandler=newHandler(Looper.getMainLooper());
    privatefinallong interval;
    privatefinalRunnabletask=newRunnable() {
        @Overridepublicvoidrun() {
            inti=0;
            Iterator<TimedItem> iterator = TimerAdapter.this.items.iterator();
            while (iterator.hasNext()) {
                TimedItemitem= iterator.next();
                if (item.isExpired()) {
                    iterator.remove();
                    notifyItemRemoved(i);
                } else {
                    i++;
                }
            }
            handler.postDelayed(this, interval);
        }
    };

    publicTimerAdapter(long interval) {
        this.interval = interval;
        handler.postDelayed(task, interval);
    }

    publicvoidaddItem(TimedItem item) {
        this.items.add(item);
    }

    publicvoidaddAll(Collection<? extends TimedItem> items) {
        this.items.addAll(items);
    }

    publicvoidclear() {
        this.items.clear();
    }

    @Overridepublic TimedItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Viewview= LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_2, parent, false);
        returnnewTimedItemHolder(view);
    }

    @OverridepublicvoidonBindViewHolder(TimedItemHolder holder, int position) {
        TimedItemitem=this.items.get(position);
        holder.getNameView().setText(item.getName());
        holder.getDescView().setText(item.getDescription());
    }

    @OverridepublicintgetItemCount() {
        returnthis.items.size();
    }

    @Overrideprotectedvoidfinalize()throws Throwable {
        super.finalize();
        handler.removeCallbacks(task);
    }
}

Finally, we can test it:

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import java.util.Random;


publicclassTestActivityextendsAppCompatActivity {
    @OverrideprotectedvoidonCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        RecyclerViewlist=newRecyclerView(this);
        list.setLayoutManager(newLinearLayoutManager(this));
        TimerAdapteradapter=newTimerAdapter(1000);
        list.setAdapter(adapter);
        setContentView(list);


        Randomrandom=newRandom();

        for (inti=0; i < 20; i++) {
            Stringname="Item: " + i;
            longexpireAt= System.currentTimeMillis() + 5000 + random.nextInt(20000);
            adapter.addItem(newTimedItem(name,expireAt));
        }

        adapter.notifyDataSetChanged();
    }
}

Post a Comment for "Removing Item From Recyclerview When Time Expired"