android特賣(mài)列表倒計(jì)時(shí)卡頓問(wèn)題的解決方法
在Android的開(kāi)發(fā)中,我們經(jīng)常遇見(jiàn)倒計(jì)時(shí)的操作,通常使用Timer和Handler共同操作來(lái)完成。當(dāng)然也可以使用Android系統(tǒng)控件CountDownTimer,這里我們封裝成一個(gè)控件,也方便大家的使用。
首先上一張效果圖吧:
說(shuō)一下造成卡頓的原因,由于滑動(dòng)的時(shí)候,adapter的getView頻繁的創(chuàng)建和銷毀,就會(huì)出現(xiàn)卡頓和數(shù)據(jù)錯(cuò)位問(wèn)題,那么我們每一個(gè)item的倒計(jì)時(shí)就需要單獨(dú)維護(hù),這里我用的Handler與timer及TimerTask結(jié)合的方法,我們知道TimerTask運(yùn)行在自己子線程,然后通過(guò)Timer的schedule()方法實(shí)現(xiàn)倒計(jì)時(shí)功能,最后通過(guò)Hander實(shí)現(xiàn)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;//倒計(jì)時(shí)的背景 private int cellBg;//每個(gè)倒計(jì)時(shí)的背景 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, attrs, 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, UIUtils.dp2px(getContext(), 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); // } // }, 0, 1000); } } public void stop() { if (timer != null) { timer.cancel(); timer = null; } } //保證天,時(shí),分,秒都兩位顯示,不足的補(bǔ)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; } } }
另一種寫(xiě)法:
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; } //設(shè)置剩余時(shí)間 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); } } /** * 如果該控件使用在碎片中,返回時(shí),則最好還是要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)); } } //倒計(jì)時(shí)結(jié)束監(jiān)聽(tīng) 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" style="@style/style_countdown" /> <TextView style="@style/style_wrap_content" android:layout_marginLeft="3dp" android:layout_marginRight="3dp" android:layout_gravity="center_vertical" android:text="時(shí)" android:textColor="@color/color_646464" /> <TextView android:id="@+id/tv_minute" style="@style/style_countdown" /> <TextView style="@style/style_wrap_content" 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" style="@style/style_countdown" /> <TextView style="@style/style_wrap_content" android:layout_marginLeft="3dp" android:layout_marginRight="3dp" android:layout_gravity="center_vertical" android:text="秒" android:textColor="@color/color_646464" /> </LinearLayout>
附上源碼地址:點(diǎn)擊打開(kāi)鏈接
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
上一篇:Android 7.0 手電筒控制實(shí)現(xiàn)
欄 目:Android
下一篇:android通過(guò)led實(shí)現(xiàn)手電筒功能
本文標(biāo)題:android特賣(mài)列表倒計(jì)時(shí)卡頓問(wèn)題的解決方法
本文地址:http://mengdiqiu.com.cn/a1/Android/9183.html
您可能感興趣的文章
- 01-10Android自定義View之繪制圓形頭像功能
- 01-10Android實(shí)現(xiàn)雙擊返回鍵退出應(yīng)用實(shí)現(xiàn)方法詳解
- 01-10android實(shí)現(xiàn)記住用戶名和密碼以及自動(dòng)登錄
- 01-10android實(shí)現(xiàn)簡(jiǎn)單計(jì)算器功能
- 01-10Android 友盟第三方登錄與分享的實(shí)現(xiàn)代碼
- 01-10android實(shí)現(xiàn)指紋識(shí)別功能
- 01-10Emoji表情在Android JNI中的兼容性問(wèn)題詳解
- 01-10Android實(shí)現(xiàn)圓形漸變加載進(jìn)度條
- 01-10android開(kāi)發(fā)環(huán)境中SDK文件夾下的所需內(nèi)容詳解
- 01-10android異步消息機(jī)制 源碼層面徹底解析(1)


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10Android自定義View之繪制圓形頭像功能
- 01-10Android實(shí)現(xiàn)雙擊返回鍵退出應(yīng)用實(shí)現(xiàn)方
- 01-10android實(shí)現(xiàn)簡(jiǎn)單計(jì)算器功能
- 01-10android實(shí)現(xiàn)記住用戶名和密碼以及自動(dòng)
- 01-10C++自定義API函數(shù)實(shí)現(xiàn)大數(shù)相乘算法
- 01-10Android 友盟第三方登錄與分享的實(shí)現(xiàn)代
- 01-10android實(shí)現(xiàn)指紋識(shí)別功能
- 01-10如何給Flutter界面切換實(shí)現(xiàn)點(diǎn)特效
- 01-10Android實(shí)現(xiàn)圓形漸變加載進(jìn)度條
- 01-10Emoji表情在Android JNI中的兼容性問(wèn)題詳
隨機(jī)閱讀
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10delphi制作wav文件的方法
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery