在AndroID的开发中,我们经常遇见倒计时的 *** 作,通常使用Timer和Handler共同 *** 作来完成。当然也可以使用AndroID系统控件CountDownTimer,这里我们封装成一个控件,也方便大家的使用。
首先上一张效果图吧:
说一下造成卡顿的原因,由于滑动的时候,adapter的getVIEw频繁的创建和销毁,就会出现卡顿和数据错位问题,那么我们每一个item的倒计时就需要单独维护,这里我用的Handler与timer及TimerTask结合的方法,我们知道TimerTask运行在自己子线程,然后通过Timer的schedule()方法实现倒计时功能,最后通过Hander实现VIEw的刷新,其核心代码如下:
public class CountDownVIEw extends linearLayout { @BindVIEw(R.ID.tv_day) TextVIEw tvDay; @BindVIEw(R.ID.tv_hour) TextVIEw tvHour; @BindVIEw(R.ID.tv_minute) TextVIEw tvMinute; @BindVIEw(R.ID.tv_second) TextVIEw tvSecond; @BindVIEw(R.ID.day) TextVIEw day; @BindVIEw(R.ID.hour) TextVIEw hour; @BindVIEw(R.ID.minute) TextVIEw minute; private Context context; private int vIEwBg;//倒计时的背景 private int cellBg;//每个倒计时的背景 private int cellTextcolor;//文字颜色 private int textcolor;//外部:等颜色 private int textSize = 14;//外部文字大小 private int cellTextSize = 12;//cell文字大小 private TimerTask timerTask = null; private Timer timer = new Timer(); private Handler handler = new Handler() { public voID handleMessage(Message msg) { countDown(); } }; public CountDownVIEw(Context context,AttributeSet attrs) { this(context,attrs,0); this.context = context; } public CountDownVIEw(Context context,AttributeSet attrs,int defStyleAttr) { super(context,defStyleAttr); this.context = context; initAttrs(attrs,defStyleAttr); initVIEw(context); } private voID initAttrs(AttributeSet attrs,int defStyle) { TypedArray typedArray = getContext().obtainStyledAttributes(attrs,R.styleable.CountDownVIEw,defStyle,0); vIEwBg = typedArray.getcolor(R.styleable.CountDownVIEw_vIEwBg,color.parsecolor("#FFFFFF")); cellBg = typedArray.getcolor(R.styleable.CountDownVIEw_cellBg,color.parsecolor("#F4F4F4")); cellTextcolor = typedArray.getcolor(R.styleable.CountDownVIEw_cellTextcolor,color.parsecolor("#646464")); textcolor = typedArray.getcolor(R.styleable.CountDownVIEw_Textcolor,color.parsecolor("#B3B3B3")); textSize = (int) typedArray.getDimension(R.styleable.CountDownVIEw_TextSize,UIUtils.dp2px(getContext(),14)); cellTextSize = (int) typedArray.getDimension(R.styleable.CountDownVIEw_cellTextSize,12)); typedArray.recycle(); } private voID initVIEw(Context context) { LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); VIEw vIEw = inflater.inflate(R.layout.layout_countdown_layout,this); ButterKnife.bind(vIEw); initproperty(); } private voID initproperty() { tvDay.setBackgroundcolor(cellBg); tvHour.setBackgroundcolor(cellBg); tvMinute.setBackgroundcolor(cellBg); tvSecond.setBackgroundcolor(cellBg); tvDay.setTextcolor(cellTextcolor); tvHour.setTextcolor(cellTextcolor); tvMinute.setTextcolor(cellTextcolor); tvSecond.setTextcolor(cellTextcolor); day.setTextcolor(textcolor); hour.setTextcolor(textcolor); minute.setTextcolor(textcolor); } public voID setleftTime(long leftTime) { if (leftTime <= 0) return; long time = leftTime / 1000; long day = time / (3600 * 24); long hours = (time - day * 3600 * 24) / 3600; long minutes = (time - day * 3600 * 24 - hours * 3600) / 60; long seconds = time - day * 3600 * 24 - hours * 3600 - minutes * 60; setTextTime(time); } public voID start() { if (timerTask == null) { timerTask = new TimerTask() { @OverrIDe public voID run() { handler.sendEmptyMessage(0); } }; timer.schedule(timerTask,1000,1000);// timer.schedule(new TimerTask() {// @OverrIDe// public voID run() {// handler.sendEmptyMessage(0);// }// },1000); } } public voID stop() { if (timer != null) { timer.cancel(); timer = null; } } //保证天,时,分,秒都两位显示,不足的补0 private voID setTextTime(long time) { String[] s = TimeUtils.formatTimer(time); tvDay.setText(s[0]); tvHour.setText(s[1]); tvMinute.setText(s[2]); tvSecond.setText(s[3]); } private voID countDown() { if (isCarry4Unit(tvSecond)) { if (isCarry4Unit(tvMinute)) { if (isCarry4Unit(tvHour)) { if (isCarry4Unit(tvDay)) { stop(); } } } } } private boolean isCarry4Unit(TextVIEw tv) { int time = Integer.valueOf(tv.getText().toString()); time = time - 1; if (time < 0) { time = 59; tv.setText(time + ""); return true; } else if (time < 10) { tv.setText("0" + time); return false; } else { tv.setText(time + ""); return false; } }}
另一种写法:
public class CountDownTimerVIEw extends linearLayout { private TextVIEw hourVIEw,minuteVIEw,secondVIEw; private limitTimer mTimer; private Handler handler; public static final int START_liMIT_TIME_MSG = 0x0111; public static final int END_liMIT_TIME_MSG = 0x0112; private long endTime,leftTime; private limitTimeListener Listener=null; public CountDownTimerVIEw(Context context) { super(context); initVIEw(context); } public CountDownTimerVIEw(Context context,AttributeSet attrs) { super(context,attrs); initVIEw(context); } private voID initVIEw(Context context) { setorIEntation(HORIZONTAL); setGravity(Gravity.CENTER_VERTICAL); inflate(context,R.layout.layout_countdown_layout,this); hourVIEw = (TextVIEw) findVIEwByID(R.ID.tv_hour); minuteVIEw = (TextVIEw) findVIEwByID(R.ID.tv_minute); secondVIEw = (TextVIEw) findVIEwByID(R.ID.tv_second); } public long getleftTime() { return leftTime; } //设置剩余时间 public voID initleftTime(long endTime) { endTime=endTime*1000; if (null != mTimer) { mTimer.cancel(); mTimer = null; } this.endTime = endTime; mTimer = new limitTimer(endTime,1000); mTimer.start(); if (handler != null) { handler.sendEmptyMessage(START_liMIT_TIME_MSG); } } /** * 如果该控件使用在碎片中,返回时,则最好还是要stop */ public voID stopTimeCount() { if (null != mTimer) { mTimer.cancel(); mTimer = null; } } public Handler getHandler() { return handler; } public voID setHandler(Handler handler) { this.handler = handler; } private class limitTimer extends CountDownTimer { public limitTimer(long millisInFuture,long countDownInterval) { super(0 != leftTime ? leftTime : endTime,countDownInterval); } @OverrIDe public voID onTick(long millisUntilFinished) { leftTime = millisUntilFinished; long totalSecond = millisUntilFinished / 1000; int second = (int) (totalSecond % 60); int minute = (int) ((totalSecond / 60) % 60); int hour = (int) ((totalSecond / 3600) % 24); int day = (int) (totalSecond / (3600 * 24)); formatVIEw(hourVIEw,hour); formatVIEw(minuteVIEw,minute); formatVIEw(secondVIEw,second); } @OverrIDe public voID onFinish() { String zero = "00"; hourVIEw.setText(zero); minuteVIEw.setText(zero); secondVIEw.setText(zero); if (null != handler) { handler.sendEmptyMessage(END_liMIT_TIME_MSG); } if (Listener!=null){ Listener.onTimeOver(true); } } private voID formatVIEw(TextVIEw vIEw,int time) { DecimalFormat df = new DecimalFormat("#00"); vIEw.setText(df.format(time)); } } //倒计时结束监听 public voID setonlimitTimeListener(limitTimeListener Listener) { this.Listener = Listener; } public interface limitTimeListener { voID onTimeOver(boolean flag); } @OverrIDe protected voID onDetachedFromWindow() { super.onDetachedFromWindow(); if (handler != null) { handler.removeMessages(START_liMIT_TIME_MSG); } }}
涉及到的布局文件
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:orIEntation="horizontal"> <TextVIEw androID:ID="@+ID/tv_hour" /> <TextVIEw androID:layout_marginleft="3dp" androID:layout_marginRight="3dp" androID:layout_gravity="center_vertical" androID:text="时" androID:textcolor="@color/color_646464" /> <TextVIEw androID:ID="@+ID/tv_minute" /> <TextVIEw androID:layout_marginleft="3dp" androID:layout_marginRight="3dp" androID:layout_gravity="center_vertical" androID:text="分" androID:textcolor="@color/color_646464" /> <TextVIEw androID:ID="@+ID/tv_second" /> <TextVIEw androID:layout_marginleft="3dp" androID:layout_marginRight="3dp" androID:layout_gravity="center_vertical" androID:text="秒" androID:textcolor="@color/color_646464" /></linearLayout>
附上源码地址:点击打开链接
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
总结以上是内存溢出为你收集整理的android特卖列表倒计时卡顿问题的解决方法全部内容,希望文章能够帮你解决android特卖列表倒计时卡顿问题的解决方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)