How to handle multiple countdown timers in RecyclerView?

I have a Recyclerview , and I need to display a countdown for each row.

Here is a similar question coutndown timers in the watchlist This has a good solution, but I need it with recyclerview

This one has a good solution, but I need it with recyclerview

enter image description here

Edit:

what I tried, here is my Adapter MyAdapter code:

  public class AdapterItems extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private ArrayList<TopCompetitions> mListItems = new ArrayList<>(); private ImageLoader mImageLoader; private Context context; private Handler handler; /******************************************/ String current_date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date d1 = null; Date d2 = null; long diff; long diffSeconds; long diffMinutes; long diffHours; long diffDays; String reachableDate = ""; /******************************************/ private ScheduledFuture updateFuture; public AdapterItems(Context context) { this.context = context; mImageLoader = AppController.getInstance().getImageLoader(); } public void setmListItems(ArrayList<TopCompetitions> mListItems) { this.mListItems = mListItems; //update the adapter to reflect the new set of mListItems notifyDataSetChanged(); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater. from(parent.getContext()). inflate(R.layout.custom_horizontal_row, parent, false); return new ItemHolder(itemView); } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { final TopCompetitions currentItem = mListItems.get(position); final ItemHolder itemHolder = (ItemHolder) holder; /* start_date , name_com_ar , name_com_en, question_en,answer_ar1,answer_ar2,answer_ar3 ,answer_en1,answer_en2,answer_en3,right_answer; */ itemHolder.item_id.setText(currentItem.getPrize_id()); itemHolder.item_description.setText(currentItem.getName_com_ar()); itemHolder.start_date.setText(currentItem.getStart_date()); itemHolder.end_date.setText(currentItem.getEnd_date()); itemHolder.name_com_ar.setText(currentItem.getName_com_ar()); itemHolder.name_com_en.setText(currentItem.getName_com_en()); itemHolder.answer_en1.setText(currentItem.getAnswer_en1()); itemHolder.answer_en2.setText(currentItem.getAnswer_en2()); itemHolder.answer_en3.setText(currentItem.getAnswer_en3()); itemHolder.answer_ar1.setText(currentItem.getAnswer_ar1()); itemHolder.answer_ar2.setText(currentItem.getAnswer_ar2()); itemHolder.answer_ar3.setText(currentItem.getAnswer_ar3()); itemHolder.right_answer.setText(currentItem.getRight_answer()); itemHolder.question_en.setText(currentItem.getQuestion_en()); itemHolder.question_ar.setText(currentItem.getQuestion_ar()); itemHolder.desc_ar.setText(currentItem.getPrize_desc_ar()); itemHolder.desc_en.setText(currentItem.getPrize_desc_en()); String urlLogo = currentItem.getPrize_pic1(); loadImages(urlLogo, itemHolder); setDefferinceTimer(itemHolder , currentItem.getEnd_date()); if (updateFuture == null) { final Handler mainHandler = new Handler(Looper.getMainLooper()); updateFuture = Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(new Runnable() { @Override public void run() { setDefferinceTimer(itemHolder , currentItem.getEnd_date()); notifyDataSetChanged(); mainHandler.post(new Runnable() { @Override public void run() { notifyDataSetChanged(); } }); } }, 0, 1000, TimeUnit.MILLISECONDS); } /* new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { new CountDownTimer(20000, 1000) { public void onTick(long millisUntilFinished) { startCountDown(itemHolder, currentItem.getEnd_date() + " 00:00:00"); notifyDataSetChanged(); } public void onFinish() { //counterTextView.setText("done!"); } }.start(); } }); */ } public void setDefferinceTimer(final RecyclerView.ViewHolder holder , String itemEndDate){ final ItemHolder itemHolder = (ItemHolder) holder; current_date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); // reachableDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(itemEndDate); try { d1 = format.parse(current_date); d2 = format.parse(itemEndDate+" 00:00:00"); } catch (ParseException e) { e.printStackTrace(); } diff = d2.getTime() - d1.getTime(); diffSeconds = diff / 1000 % 60; diffMinutes = diff / (60 * 1000) % 60; diffHours = diff / (60 * 60 * 1000) % 24; diffDays = diff / (24 * 60 * 60 * 1000); itemHolder.days_tf.setText(""+diffDays); itemHolder.hours_tf.setText(""+diffHours); itemHolder.minutes_tf.setText(""+diffMinutes); itemHolder.seconds_tf.setText(""+diffSeconds); } private void loadImages(String urlThumbnail, final RecyclerView.ViewHolder holder) { final ItemHolder itemHolder = (ItemHolder) holder; mImageLoader.get(urlThumbnail, new ImageLoader.ImageListener() { @Override public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) { itemHolder.item_image.setImageBitmap(response.getBitmap()); //holder.salon_gender.setImageBitmap(response.getBitmap()); } @Override public void onErrorResponse(VolleyError error) { } }); } @Override public int getItemCount() { return mListItems.size(); } private class ItemHolder extends RecyclerView.ViewHolder { public TextView item_id, item_description, end_date, start_date, name_com_ar, name_com_en, question_ar, question_en, answer_ar1, answer_ar2, answer_ar3, answer_en1, answer_en2, answer_en3, right_answer , desc_ar , desc_en; public TextView days_tf, hours_tf, minutes_tf, seconds_tf; public CircleImageView item_image; public ItemHolder(View itemView) { super(itemView); start_date = (TextView) itemView.findViewById(R.id.start_date); end_date = (TextView) itemView.findViewById(R.id.end_date); name_com_ar = (TextView) itemView.findViewById(R.id.name_com_ar); name_com_en = (TextView) itemView.findViewById(R.id.name_com_en); question_en = (TextView) itemView.findViewById(R.id.question_en); question_ar = (TextView) itemView.findViewById(R.id.question_ar); desc_ar = (TextView) itemView.findViewById(R.id.desc_ar); desc_en = (TextView) itemView.findViewById(R.id.desc_en); answer_ar1 = (TextView) itemView.findViewById(R.id.answer_ar1); answer_ar2 = (TextView) itemView.findViewById(R.id.answer_ar2); answer_ar3 = (TextView) itemView.findViewById(R.id.answer_ar3); answer_en1 = (TextView) itemView.findViewById(R.id.answer_en1); answer_en2 = (TextView) itemView.findViewById(R.id.answer_en2); answer_en3 = (TextView) itemView.findViewById(R.id.answer_en3); right_answer = (TextView) itemView.findViewById(R.id.right_answer); item_id = (TextView) itemView.findViewById(R.id.item_id); item_description = (TextView) itemView.findViewById(R.id.item_description); item_image = (CircleImageView) itemView.findViewById(R.id.item_image); days_tf = (TextView) itemView.findViewById(R.id.days_tf); hours_tf = (TextView) itemView.findViewById(R.id.hours_tf); minutes_tf = (TextView) itemView.findViewById(R.id.minutes_tf); seconds_tf = (TextView) itemView.findViewById(R.id.seconds_tf); } } 
+4
source share
4 answers

Add a CountDownTimer element to the ViewHolder . In getView() set and run the counter and do not forget to cancel any existing ViewHolder in the same instance. In onTick() you need to update the value on the display, and not start the counter.

+2
source

A simple solution would be:

 Handler handler=new Handler(); handler.postDelayed(new UpdateTimerThread(holder),0); public Class UpdateTimerThread implements Runnable{ Holder holder; public UpdateTimerThread(Holder holder){ this.holder=holder; } @Override public void run() { lgetCreatedTime = lgetCreatedTime + 1000; long diffSeconds; long diffMinutes; long diffHours; diffSeconds = lgetCreatedTime / 1000 % 60; diffMinutes = lgetCreatedTime / (60 * 1000) % 60; diffHours = lgetCreatedTime / (60 * 60 * 1000) % 24; holder.GameTimer.setText(String.format("%02d:%02d:%02d", diffHours, diffMinutes, diffSeconds)); handler.postDelayed(this,1000); } } 

Note: 1.holder is an object of the ViewHolder class

2.Creating the UpdateTimerThread class implements Runnable

3.Turn the date and time to long and save in lgetCreatedTime

4.Run Handler for every 1 second to time stamp

+2
source

You can create the CountDownTimer link in the ViewHolder class and create your instance in the onBindViewHolder adapter method.

It works great.

Tested.

0
source

Here you can check and download the source code Countdown Timers in RecyclerView

activity_main.xml

 <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" xmlns:android="http://schemas.android.com/apk/res/android"&gt; <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:scrollbars="vertical" /> </RelativeLayout> 

adapter_layout.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="15dp" android:padding="10dp" android:id="@+id/tv_timer"/> </LinearLayout> 

MainActivity.java

 package com.androidsolutionworld.multipletimer; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.widget.LinearLayout; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private RecyclerView recyclerView; private ArrayList al_data = new ArrayList<>(); private Adapter obj_adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerView = (RecyclerView)findViewById(R.id.recycler_view); al_data.add("1234"); al_data.add("1257"); al_data.add("100"); al_data.add("1547"); al_data.add("200"); al_data.add("500"); al_data.add("2000"); al_data.add("1000"); obj_adapter = new Adapter(al_data); LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext(),LinearLayoutManager.VERTICAL,false); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(obj_adapter); } } 

Custom adapter:

 import android.os.CountDownTimer; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import java.util.ArrayList; public class Adapter extends RecyclerView.Adapter{ private ArrayList al_data; public class MyViewHolder extends RecyclerView.ViewHolder{ public TextView tv_timer; CountDownTimer timer; public MyViewHolder (View view){ super(view); tv_timer = (TextView)view.findViewById(R.id.tv_timer); } } public Adapter(ArrayList al_data) { this.al_data = al_data; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_layout,parent,false); return new MyViewHolder(view); } @Override public void onBindViewHolder(final MyViewHolder holder, int position) { holder.tv_timer.setText(al_data.get(position)); if (holder.timer != null) { holder.timer.cancel(); } long timer = Long.parseLong(al_data.get(position)); timer = timer*1000; holder.timer = new CountDownTimer(timer, 1000) { public void onTick(long millisUntilFinished) { holder.tv_timer.setText("" + millisUntilFinished/1000 + " Sec"); } public void onFinish() { holder.tv_timer.setText("00:00:00"); } }.start(); } @Override public int getItemCount() { return al_data.size(); } } 
-1
source

All Articles