Android: Multiple simultaneous count-down timers in a ListView

前端 未结 4 601
说谎
说谎 2020-12-30 08:12

I am creating an app that requires a ListView with an undetermined number of elements, each of which has a timer that counts down from a variable number. I am able to succes

4条回答
  •  有刺的猬
    2020-12-30 08:25

    This is an example of the way I do it and it works perfect:

    public class TestCounterActivity extends ListActivity
    {
        TestAdapter adapter;
    
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
    
            // Example values
            ArrayList values = new ArrayList();
            values.add(new Date(1482464366239L));
            values.add(new Date(1480464366239L));
            values.add(new Date(1470464366239L));
            values.add(new Date(1460464366239L));
            values.add(new Date(1450464366239L));
            values.add(new Date(1440464366239L));
            values.add(new Date(1430464366239L));
            values.add(new Date(1420464366239L));
            values.add(new Date(1410464366239L));
            values.add(new Date(1490464366239L));
    
            adapter = new TestAdapter(this, values);
    
            setListAdapter(adapter);
        }
    
        @Override
        protected void onStop()
        {
            super.onStop();
    
            // Dont forget to cancel the running timers
            adapter.cancelAllTimers();
        }
    }
    

    And this is the adapter

    public class TestAdapter extends ArrayAdapter 
    {
        private final Activity context;
        private final List values;
        private HashMap counters;
    
        static class TestViewHolder 
        {
            public TextView tvCounter;
        }
    
        public TestAdapter(Activity context, List values) 
        {
            super(context, R.layout.test_row, values);
            this.context = context;
            this.values = values;
            this.counters = new HashMap();
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) 
        {
            View rowView = convertView;
    
            if(rowView == null)
            {
                LayoutInflater inflater = context.getLayoutInflater();
                rowView = inflater.inflate(R.layout.test_row, null);
                final TestViewHolder viewHolder = new TestViewHolder();
                viewHolder.tvCounter = (TextView) rowView.findViewById(R.id.tvCounter);
    
                rowView.setTag(viewHolder);
            }
    
            TestViewHolder holder = (TestViewHolder) rowView.getTag();
            final TextView tv = holder.tvCounter;
    
            CountDownTimer cdt = counters.get(holder.tvCounter);
            if(cdt!=null)
            {
                cdt.cancel();
                cdt=null;
            }
    
            Date date = values.get(position);
            long currentDate = Calendar.getInstance().getTime().getTime();
            long limitDate = date.getTime();
            long difference = limitDate - currentDate;
    
            cdt = new CountDownTimer(difference, 1000)
            {
                @Override
                public void onTick(long millisUntilFinished) 
                {
                    int days = 0;
                    int hours = 0;
                    int minutes = 0;
                    int seconds = 0;
                    String sDate = "";
    
                    if(millisUntilFinished > DateUtils.DAY_IN_MILLIS)
                    {
                        days = (int) (millisUntilFinished / DateUtils.DAY_IN_MILLIS);
                        sDate += days+"d";
                    }
    
                    millisUntilFinished -= (days*DateUtils.DAY_IN_MILLIS);
    
                    if(millisUntilFinished > DateUtils.HOUR_IN_MILLIS)
                    {
                        hours = (int) (millisUntilFinished / DateUtils.HOUR_IN_MILLIS);
                    }
    
                    millisUntilFinished -= (hours*DateUtils.HOUR_IN_MILLIS);
    
                    if(millisUntilFinished > DateUtils.MINUTE_IN_MILLIS)
                    {
                        minutes = (int) (millisUntilFinished / DateUtils.MINUTE_IN_MILLIS);
                    }
    
                    millisUntilFinished -= (minutes*DateUtils.MINUTE_IN_MILLIS);
    
                    if(millisUntilFinished > DateUtils.SECOND_IN_MILLIS)
                    {
                        seconds = (int) (millisUntilFinished / DateUtils.SECOND_IN_MILLIS);
                    }
    
                    sDate += " "+String.format("%02d",hours)+":"+String.format("%02d",minutes)+":"+String.format("%02d",seconds);
                    tv.setText(sDate.trim());
                }
    
                @Override
                public void onFinish() {
                    tv.setText("Finished");
                }
            };
    
            counters.put(tv, cdt);
            cdt.start();
    
            return rowView;
        }
    
        public void cancelAllTimers()
        {
            Set> s = counters.entrySet();
            Iterator it = s.iterator();
            while(it.hasNext())
            {
                try
                {
                    Map.Entry pairs = (Map.Entry)it.next();
                    CountDownTimer cdt = (CountDownTimer)pairs.getValue();
    
                    cdt.cancel();
                    cdt = null;
                }
                catch(Exception e){}
            }
    
            it=null;
            s=null;
            counters.clear();
        }
    }
    

提交回复
热议问题