How to handle multiple countdown timers in RecyclerView?

后端 未结 5 2212
长情又很酷
长情又很酷 2021-02-10 06:45

I have a Recyclerview , and I need to display a countdown on every row.

Here is a similar question coutndown timers in listview It has a good solution ,

相关标签:
5条回答
  • 2021-02-10 07:13

    After 6 hours I finally found how to use it. However, I couldn't find the same way with the Runnable.

    I'm using this code and it works for me:

    @Override
    public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date event_date = dateFormat.parse(laterStart.toString());
            current_date = dateFormat.parse(laterCurrent.toString());
            Date diff = event_date.getTime() - current_date.getTime();
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        //Very important code for some problems
        if (holder.timer != null) {
            holder.timer.cancel();
        }
    
        holder.timer = new CountDownTimer(diff, 900) {
            @Override
            public void onTick(long millisUntilFinished) {
                long day = TimeUnit.MILLISECONDS.toDays(millisUntilFinished);
                millisUntilFinished -= TimeUnit.DAYS.toMillis(day);
    
                long hour = TimeUnit.MILLISECONDS.toHours(millisUntilFinished);
                millisUntilFinished -= TimeUnit.HOURS.toMillis(hour);
    
                long minute = TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished);
                millisUntilFinished -= TimeUnit.MINUTES.toMillis(minute);
    
                long second = TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished);
    
    
                holder.timeText.setText(day+":"+hour+":"+minute+":"+second);
            }
    
            @Override
            public void onFinish() {
            }
        }.start();
    }
    

    And RecycleView ViewHolder class:

    public class ViewHolder extends RecyclerView.ViewHolder {
    ***your codes***
    
       //Just add CountDownTimer
       CountDownTimer timer;
    
    *** your codes ***
    }
    
    0 讨论(0)
  • 2021-02-10 07:15

    Add a CountDownTimer member in the ViewHolder. In getView() set and start the counter, and don't forget to cancel any existing one in the same instance of ViewHolder. In onTick() you need to update the value on the display, not start the counter.

    0 讨论(0)
  • 2021-02-10 07:15

    The 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 the object of ViewHolder class

    2.Create a class UpdateTimerThread implements Runnable

    3.Convert Date and Time to long and store into lgetCreatedTime

    4.Run Handler for every 1 Sec to tick the Time

    0 讨论(0)
  • 2021-02-10 07:16

    Here you can check and download the source code of Countdown timers in a 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();
    }
    
    }
    
    0 讨论(0)
  • 2021-02-10 07:26

    You can create CountDownTimer reference in ViewHolder class and create its instance in onBindViewHolder method of Adapter.

    It works perfectly.

    Tested Myself.

    0 讨论(0)
提交回复
热议问题