版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】怎么解决android特卖列表倒计时卡顿问题
这篇文章将为大家详细讲解有关怎么解决android特卖列表倒计时卡顿问题,在下觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。在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,
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;
}
}
//保证天,时,分,秒都两位显示,不足的补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="/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 人教版六年级下册数学期末测试卷及1套参考答案
- 人教版六年级下册数学期末测试卷及答案参考
- 人教版六年级下册数学期末测试卷含完整答案(必刷)
- 人教版六年级下册数学期末测试卷(考点精练)
- 人教版四年级下册数学期末测试卷【学生专用】
- 人教版四年级下册数学期末测试卷及答案【考点梳理】
- 人教版四年级下册数学期末测试卷附答案【b卷】
- 小学六年级下册数学期末测试卷【考试直接用】
- 小学六年级下册数学期末测试卷含答案(夺分金卷)
- 小学六年级下册数学期末测试卷附答案(完整版)
- 嫁娶择日要点
- 卡拉OK仿真系统音频功率放大的设计
- 痛风中医临床路径.docx
- 综合楼工程施工组织设计毕业设计任务书
- 三级医院评审过关手册(超详细)
- 月之故乡F调 五线谱正谱 钢琴伴奏谱 高清晰
- 材料力学与结构力学visio模具下载
- 上海市单位退工证明退工单
- (完整版)英文四线格A4纸打印模板(最新整理)
- 南京英文介绍
- 医学影像学面试常见考题
评论
0/150
提交评论