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;
}
}
}
移动技术交流(Android,ios,RactNtive),请加群:278792776
附上源码地址:点击打开链接
android 特卖列表倒计时卡顿问题的更多相关文章
- 4.Android App 优化之消除卡顿
转载:http://gold.xitu.io/post/582583328ac247004f3ab124 1, 感知卡顿 用户对卡顿的感知, 主要来源于界面的刷新. 而界面的性能主要是依赖于设备的UI ...
- cocos2d-x android黑屏后返回游戏卡顿
转自:http://blog.csdn.net/wolfking_2009/article/details/8824931 2013年5月17日更新:对于之前说的资源释放问题,cocos2d-x 2. ...
- Android ScrollView嵌套Recyclerview滑动卡顿,松手即停问题解决;
假如你的布局类似这样的: <ScrollView android:layout_width="match_parent" android:layout_height=&quo ...
- Android fragment 切换载入数据卡顿问题
接着上一篇项目的进度.上一篇讲了怎样利用fragment来实现下拉菜单.公用菜单,以实现切换主界面数据的功能,这时候遇到的问题是:使用了fragment的切换界面方法.但载入的数据太多.用户从一个界面 ...
- Android 布局渲染流程与卡顿优化
文章内容概要 一.手机界面UI渲染显示流程 二.16ms原则 三.造成卡顿的原因 四.过度绘制介绍.检测工具.如何避免造成过度绘制造成的卡顿 一.手机界面UI渲染显示流程 大家都知道CPU(中央处理器 ...
- PullToRefreshScrollView 嵌套RecyclerView实现特卖列表倒计时抢购
不久之前,我们谈到了通过Handler与timer及TimerTask结合实现倒计时抢购列表,那个是PullToRefreshListView实现的,今天要讲的是PullToRefreshScroll ...
- M创aterial Design作风Android申请书--创建列表和卡
本人全部文章首先公布于个人博客,欢迎关注,地址:http://blog.isming.me 上次说过使用主题,应用Material Design的样式,同一时候卡片布局也是Material Desig ...
- Android中scrollview嵌套HorizontalScrollView卡顿现象解决
开发中经验会遇到滑动里面嵌入滑动的问题,但是这种情况下触摸事件就会发生冲突.导致滑动非常卡,甚至出现程序停止响应.这种情况下我们一般需要重写view.下面给出重新scrollview的方法 publi ...
- [UI列表]LoopScrollRect无限滑动不卡顿
应用场景 对于背包界面,排行榜列表,聊天消息,等有大量的UI列表的界面,常规做法是为每一条数据生成一个格子,在数据量越大的情况下,会生成越来越多的Gameobject,引起卡顿. 这篇文章讲述的就是解 ...
随机推荐
- 【Codeforces Round #430 (Div. 2) A C D三个题】
·不论难度,A,C,D自己都有收获! [A. Kirill And The Game] ·全是英文题,述大意: 给出两组区间端点:l,r,x,y和一个k.(都是正整数,保证区间不为空),询问是否 ...
- bzoj 3930: [CQOI2015]选数
Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公 ...
- BZOJ4589 Hard Nim(快速沃尔什变换模板)
终于抽出时间来学了学,比FFT不知道好写到哪里去. #include <cstdio> typedef long long ll; ,p=1e9+; int k,m,n,a[N],pi[N ...
- I/O控制的主要功能
主要功能: 1. 解释用户的I/O系统调用.将用户I/O系统调用转换为I/O控制模块认识的命令模式. 2. 设备驱动.根据得到的I/O命令,启动物理设备完成指定的I/O操作. 3. 中断处理.对 ...
- 笔记12 注入AspectJ切面
虽然Spring AOP能够满足许多应用的切面需求,但是与AspectJ相比, Spring AOP 是一个功能比较弱的AOP解决方案.AspectJ提供了Spring AOP所不能支持的许多类型的切 ...
- Java后缀数组-求sa数组
后缀数组的一些基本概念请自行百度,简单来说后缀数组就是一个字符串所有后缀大小排序后的一个集合,然后我们根据后缀数组的一些性质就可以实现各种需求. public class MySuffixArrayT ...
- mysql服务无法正常启动
这个时候多半是ini文件出了问题. 1.去检查你的my.ini的保存编码格式是不是ANSI,如果不是将其改为ANSI (一般我们修改my.ini时,都无法直接保存,而是选择另存为在其他目录下,再去替换 ...
- BookNote: Refactoring - Improving the Design of Existing Code
BookNote: Refactoring - Improving the Design of Existing Code From "Refactoring - Improving the ...
- java.lang.NumberFormatException: For input string: " "
原因:这个异常是说,在将字符串""转换为number的时候格式化错误.额,很简单的异常,以前我是写个方法,然后遍历对比不正确的数字或者用正则表达式之类的.现在发现一个很漂亮的方法, ...
- 批量录入快递地址-快宝地址服务(PHP代码示例)
快递地址写错了怎么办?快递地址写的不详细怎么办?怎么皮批量录入收件人地址?微商怎么批量录入发件人地址?快宝地址清洗,有效的解决了寄送快递时,批量录入收件人信息.发件人信息时,纠正地址数据,不完整地址识 ...