Android 用 ListView 实现倒计时列表功能


在很多时候我们会用到一个场景,在 list 的 item 上显示不同的倒计时,如下图所示。

listView效果

需要注意的地方也没多少:

1.ViewHolder 的重复使用与倒计时显示冲突。2.退出应用时释放所有 CountDownTimer 资源。

关于使用 Android 用 RecyclerView 实现倒计时列表功能。

Step00.核心代码 MyAdapter.java

public static class MyAdapter extends BaseAdapter {    private List mDatas;    private Context mContext;    //用于退出 Activity,避免 Countdown,造成资源浪费。    private SparseArray countDownCounters;    public MyAdapter(Context mContext, List mDatas) {        this.mContext = mContext;        this.mDatas = mDatas;        this.countDownCounters = new SparseArray<>();    }    /**     * 清空当前 CountTimeDown 资源     */    public void cancelAllTimers() {        if (countDownCounters == null) {            return;        }        Log.e("TAG",  "size :  " + countDownCounters.size());        for (int i = 0, length = countDownCounters.size(); i < length; i++) {            CountDownTimer cdt = countDownCounters.get(countDownCounters.keyAt(i));            if (cdt != null) {                cdt.cancel();            }        }    }    @Override    public int getCount() {        if (mDatas != null && !mDatas.isEmpty()) {            return mDatas.size();        }        return 0;    }    @Override    public Object getItem(int position) {        if (mDatas != null && !mDatas.isEmpty()) {            return mDatas.get(position);        }        return null;    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        final ViewHolder viewHolder;        if (convertView == null) {            convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item_common, parent, false);            viewHolder = new ViewHolder();            viewHolder.statusTv = (TextView) convertView.findViewById(R.id.tv_status);            viewHolder.timeTv = (TextView) convertView.findViewById(R.id.tv_time);            convertView.setTag(viewHolder);        } else {            viewHolder = (ViewHolder) convertView.getTag();        }        final TimerItem data = mDatas.get(position);        viewHolder.statusTv.setText(data.name);        CountDownTimer countDownTimer = countDownCounters.get(viewHolder.timeTv.hashCode());        if (countDownTimer != null) {            //将复用的倒计时清除            countDownTimer.cancel();        }        long timer = data.expirationTime;        timer = timer - System.currentTimeMillis();        //expirationTime 与系统时间做比较,timer 小于零,则此时倒计时已经结束。        if (timer > 0) {            countDownTimer = new CountDownTimer(timer, 1000) {                public void onTick(long millisUntilFinished) {                    viewHolder.timeTv.setText(TimeTools.getCountTimeByLong(millisUntilFinished));                    Log.e("TAG", data.name + " :  " + millisUntilFinished);                }                public void onFinish() {                    viewHolder.timeTv.setText("00:00:00");                    viewHolder.statusTv.setText(data.name + ":结束");                }            }.start();            //将此 countDownTimer 放入list.            countDownCounters.put(viewHolder.timeTv.hashCode(), countDownTimer);        } else {            viewHolder.timeTv.setText("00:00:00");            viewHolder.statusTv.setText(data.name + ":结束");        }        return convertView;    }    public class ViewHolder {        public TextView statusTv;        public TextView timeTv;    }}

主要通过 SparseArray 类保存每个 Item 上的 CountDownTimer 类。
当需要复用时,通用 TextView 的 hashCode 取出对应的 CountDownTimer。重新启动并显示。
当退出此页面时,调用 cancelAllTimers() 方法,遍历 countDownCounters 关闭所有的 CountDownTimer 类。避免造成内存泄漏。

Step01.数据填充

mAdapter = new MyAdapter(mContext,TimerItemUtil.getTimerItemList());mListView.setAdapter(mAdapter);

Step02.Entity 类

public class TimerItem {    //其他属性    public String name;    //倒计时长,单位毫秒    public long expirationTime;    public TimerItem(String name, long expirationTime) {        this.name = name;        this.expirationTime = expirationTime;    }}

Step03.获取倒计时集合(自定义时间)。

public static List getTimerItemList() {    List lstTimerItems = new ArrayList<>();    lstTimerItems.add(new TimerItem("A", System.currentTimeMillis() + 11 * 1000));    lstTimerItems.add(new TimerItem("B", System.currentTimeMillis() + 22 * 1000));    lstTimerItems.add(new TimerItem("C", System.currentTimeMillis() + 26 * 1000));    lstTimerItems.add(new TimerItem("D", System.currentTimeMillis() + 33 * 1000));    lstTimerItems.add(new TimerItem("E", System.currentTimeMillis() + 24 * 1000));    lstTimerItems.add(new TimerItem("F", System.currentTimeMillis() + 98 * 1000));    lstTimerItems.add(new TimerItem("G", System.currentTimeMillis() + 14 * 1000));    lstTimerItems.add(new TimerItem("H", System.currentTimeMillis() + 36 * 1000));    lstTimerItems.add(new TimerItem("I", System.currentTimeMillis() + 58 * 1000));    lstTimerItems.add(new TimerItem("J", System.currentTimeMillis() + 47 * 1000));    lstTimerItems.add(new TimerItem("K", System.currentTimeMillis() + 66 * 1000));    lstTimerItems.add(new TimerItem("L", System.currentTimeMillis() + 55 * 1000));    lstTimerItems.add(new TimerItem("M", System.currentTimeMillis() + 62 * 1000));    lstTimerItems.add(new TimerItem("N", System.currentTimeMillis() + 45 * 1000));    lstTimerItems.add(new TimerItem("O", System.currentTimeMillis() + 14 * 1000));    return lstTimerItems;}

Step04.list_item_common.xml

<?xml version="1.0" encoding="utf-8"?>        

Step05.当退出 Activity 时释放资源.

@Overrideprotected void onDestroy() {    super.onDestroy();    if (mAdapter != null) {        mAdapter.cancelAllTimers();    }}

Step06.源代码 Github

更多相关文章

  1. Android(安卓)滑动效果入门篇(二)—— Gallery
  2. android实现View的渐隐渐现功能
  3. 基于安卓手持设备的手机应用编程——用户界面
  4. Android之Android(安卓)Studio三种方式导入外部资源 以及 报错处
  5. Android(安卓)蓝牙开发(九)A2DP基本功能
  6. 8大你不得不知的Android调试工具
  7. Android的Context简介
  8. Android(安卓)xml 中@和问号?等解释
  9. Android(安卓)apk动态加载机制的研究(二):资源加载和activity生命周

随机推荐

  1. Android 仿微信TabHost使用方法详解
  2. PullToRefreshScrollView和Banner
  3. Android Baseline小tip
  4. android ProgressBar用法
  5. Android通知权限相关工具类
  6. Android第一枪
  7. Android 的res/values/colors自定义颜色
  8. android 变长数据GSON解析
  9. Android studio 自定义view 画圆
  10. Android隐藏ListView分割线