倒计时实现方案总结 Timer Handler
利用Timer实现倒计时
@BindView(R.id.send) Button send;//发送验证码
private int time = 60;//倒计时
private Timer timer;
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 1:
send.setText(time + "S");
break;
case 2:
send.setEnabled(true);
send.setText("重新发送");
break;
}
}
};
@OnClick({R.id.send, R.id.next})
public void onClickIv(View v) {
switch (v.getId()) {
case R.id.send:
send.setEnabled(false);
getVerificationCode();
break;
}
}
//定时器
private void setTimer() {
timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
time--;
if (time > 0) handler.sendEmptyMessage(1);
else {
handler.sendEmptyMessage(2);
destoryTimer();
}
}
};
timer.schedule(task, 0, 1000);
}
private void destoryTimer() {
if (timer != null) {
timer.cancel();
timer = null;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
destoryTimer();
}
TimerTask task = new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
time--;
if (time > 0) send.setText(time + "S");
else {
send.setEnabled(true);
send.setText("重新发送");
destoryTimer();
}
}
});
}
};
利用Handler实现倒计时
handler.sendMessageDelayed(handler.obtainMessage(1), 1000);
final Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
time--;
if (time > 0) {
send.setText(time + "S");
handler.sendMessageDelayed(handler.obtainMessage(1), 1000);
} else {
send.setEnabled(true);
send.setText("重新发送");
}
}
}
};
Handler handler = new Handler();
handler.postDelayed(runnable, 1000);
Runnable runnable = new Runnable() {
@Override
public void run() {
time--;
if (time > 0) {
send.setText(time + "S");
handler.postDelayed(this, 1000);
} else {
send.setEnabled(true);
send.setText("重新发送");
}
}
};
利用CountDownTimer实现
CountDownTimer timer = new CountDownTimer(60000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
send.setText(time + "S");
}
@Override
public void onFinish() {
send.setEnabled(true);
send.setText("重新发送");
}
};
GitHub上星星最多的倒计时控件
compile 'com.github.iwgang:countdownview:2.1.3'
<cn.iwgang.countdownview.CountdownView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
CountdownView mCountdownView = (CountdownView)findViewById(R.id.countdownView);
mCountdownView.start(995550000); // 毫秒
// 或者自己编写倒计时逻辑,然后调用updateShow来更新UI
for (int time=0; time<1000; time++) {
mCountdownView.updateShow(time);
}
mCountdownView.dynamicShow(DynamicConfig dynamicConfig)
倒计时结束后回调
mCountdownView.setOnCountdownEndListener(OnCountdownEndListener);
指定间隔时间回调
mCountdownView.setOnCountdownIntervalListener(long, OnCountdownIntervalListener);
RecyclerView中倒计时方案1【最简单】
//定时器,用于刷新GridView的数据源
private void setQryTimer() {
cancelQryTimer();
qryTimer = new Timer();
qryTimer.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
if (fixRpList != null && fixRpList.size() > 0) {
for (FixRpBean item : fixRpList) {
if (item.diff_time >= 0) item.diff_time = item.diff_time - 1000L;
}
if (fixRpDialog != null) fixRpDialog.upDate(fixRpList);
}
}
});
}
}, 0, 1000);
}
public void upDate(List<FixRpBean> redPacketList) {
list.clear();
list.addAll(redPacketList);
mRecyclerView.getAdapter().notifyDataSetChanged();//建议使用RecyclerView的局部刷新功能
}
RecyclerView中倒计时方案2【推荐】
/**
* 复用 本地的计时器 —— System.currentTimeMillis(), 不必自行计时
*/
public class RecyclerViewActivity extends Activity {
private List<ItemInfo> mDataList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recyclerview);
initData();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv);
recyclerView.setAdapter(new MyAdapter(this, mDataList));
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
recyclerView.setItemAnimator(new DefaultItemAnimator());
}
private void initData() {
mDataList = new ArrayList<>();
for (int i = 1; i < 20; i++) {
mDataList.add(new ItemInfo(i * 20 * 1000));
}
// 校对倒计时
long curTime = System.currentTimeMillis();
for (ItemInfo itemInfo : mDataList) {
itemInfo.endTime = curTime + itemInfo.countdown;
}
}
static class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
private Context mContext;
private List<ItemInfo> mDatas;
public MyAdapter(Context context, List<ItemInfo> datas) {
this.mContext = context;
this.mDatas = datas;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false));
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.bindData(mDatas.get(holder.getAdapterPosition()));
}
@Override
public int getItemCount() {
return mDatas.size();
}
//**************************************************关键代码****************************************
@Override
public void onViewAttachedToWindow(MyViewHolder holder) {
super.onViewAttachedToWindow(holder);//父类中为空代码
holder.refreshTime(mDatas.get(holder.getAdapterPosition()).endTime - System.currentTimeMillis());
}
@Override
public void onViewDetachedFromWindow(MyViewHolder holder) {
super.onViewDetachedFromWindow(holder);
holder.countdownView.stop();
}
//**************************************************关键代码****************************************
}
static class MyViewHolder extends RecyclerView.ViewHolder {
public CountdownView countdownView;
public MyViewHolder(View itemView) {
super(itemView);
countdownView = (CountdownView) itemView.findViewById(R.id.countdownView);
}
public void bindData(ItemInfo itemInfo) {
refreshTime(itemInfo.endTime - System.currentTimeMillis());
}
public void refreshTime(long leftTime) {
if (leftTime > 0) {
countdownView.start(leftTime);
} else {
countdownView.stop();//停止计时器,mCustomCountDownTimer.stop();
countdownView.allShowZero();//所有计时清零,即mCountdown.setTimes(0, 0, 0, 0, 0);
}
}
}
static class ItemInfo {
public long countdown;
/*
根据服务器返回的countdown换算成手机对应的开奖时间 (毫秒)
[正常情况最好由服务器返回countdown字段,然后客户端再校对成该手机对应的时间,不然误差很大]
*/
public long endTime;
public ItemInfo(long countdown) {
this.countdown = countdown;
}
}
}
RecyclerView中倒计时方案3【最麻烦】
/*
自己维护倒计时任何,再调用countdownView.updateShow来刷新显示
*/
public class RecyclerViewActivity2 extends AppCompatActivity {
private MyAdapter mMyAdapter;
private List<ItemInfo> mDataList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recyclerview);
initData();
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv);
mMyAdapter = new RecyclerViewActivity2.MyAdapter(this, mDataList);
recyclerView.setAdapter(mMyAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
recyclerView.setItemAnimator(new DefaultItemAnimator());
}
private void initData() {
mDataList = new ArrayList<>();
for (int i = 1; i < 20; i++) {
mDataList.add(new ItemInfo(1000 + i, "RecyclerView_测试标题_" + i, i * 20 * 1000));
}
// 校对倒计时
long curTime = System.currentTimeMillis();
for (ItemInfo itemInfo : mDataList) {
itemInfo.setEndTime(curTime + itemInfo.getCountdown());
}
}
@Override
protected void onResume() {
super.onResume();
if (null != mMyAdapter)
mMyAdapter.startRefreshTime();}
@Override
protected void onPause() {
super.onPause();
if (null != mMyAdapter)
mMyAdapter.cancelRefreshTime();}
@Override
public void onDestroy() {
super.onDestroy();
if (null != mMyAdapter)
mMyAdapter.cancelRefreshTime();}
static class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
private Context mContext;
private List<ItemInfo> mDatas;
private final SparseArray<MyViewHolder> mCountdownVHList;
private Handler mHandler = new Handler();
private Timer mTimer;
private boolean isCancel = true;
public MyAdapter(Context context, List<ItemInfo> datas) {
this.mContext = context;
this.mDatas = datas;
mCountdownVHList = new SparseArray<>();
startRefreshTime();
}
public void startRefreshTime() {
if (!isCancel) return;
if (null != mTimer) mTimer.cancel();
isCancel = false;
mTimer = new Timer();
mTimer.schedule(new TimerTask() {
@Override
public void run() {
mHandler.post(mRefreshTimeRunnable);
}
}, 0, 10);
}
public void cancelRefreshTime() {
isCancel = true;
if (null != mTimer) {
mTimer.cancel();
}
mHandler.removeCallbacks(mRefreshTimeRunnable);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false));
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
ItemInfo curItemInfo = mDatas.get(position);
holder.bindData(curItemInfo);
// 处理倒计时
if (curItemInfo.getCountdown() > 0) {
synchronized (mCountdownVHList) {
mCountdownVHList.put(curItemInfo.getId(), holder);
}
}
}
@Override
public int getItemCount() {
return mDatas.size();
}
@Override
public void onViewRecycled(MyViewHolder holder) {
super.onViewRecycled(holder);
ItemInfo curAnnounceGoodsInfo = holder.getBean();
if (null != curAnnounceGoodsInfo && curAnnounceGoodsInfo.getCountdown() > 0) {
mCountdownVHList.remove(curAnnounceGoodsInfo.getId());
}
}
private Runnable mRefreshTimeRunnable = new Runnable() {
@Override
public void run() {
if (mCountdownVHList.size() == 0) return;
synchronized (mCountdownVHList) {
long currentTime = System.currentTimeMillis();
int key;
for (int i = 0; i < mCountdownVHList.size(); i++) {
key = mCountdownVHList.keyAt(i);
MyViewHolder curMyViewHolder = mCountdownVHList.get(key);
if (currentTime >= curMyViewHolder.getBean().getEndTime()) {
curMyViewHolder.getBean().setCountdown(0);// 倒计时结束
mCountdownVHList.remove(key);
notifyDataSetChanged();
} else {
curMyViewHolder.refreshTime(currentTime);
}
}
}
}
};
}
static class MyViewHolder extends RecyclerView.ViewHolder {
private TextView mTvTitle;
private CountdownView mCvCountdownView;
private ItemInfo mItemInfo;
public MyViewHolder(View itemView) {
super(itemView);
mTvTitle = (TextView) itemView.findViewById(R.id.tv_title);
mCvCountdownView = (CountdownView) itemView.findViewById(R.id.cv_countdownView);
}
public void bindData(ItemInfo itemInfo) {
mItemInfo = itemInfo;
if (itemInfo.getCountdown() > 0) {
refreshTime(System.currentTimeMillis());
} else {
mCvCountdownView.allShowZero();
}
mTvTitle.setText(itemInfo.getTitle());
}
public void refreshTime(long curTimeMillis) {
if (null == mItemInfo || mItemInfo.getCountdown() <= 0) return;
mCvCountdownView.updateShow(mItemInfo.getEndTime() - curTimeMillis);
}
public ItemInfo getBean() {
return mItemInfo;
}
}
static class ItemInfo {
private int id;
private String title;
private long countdown;
/*
根据服务器返回的countdown换算成手机对应的开奖时间 (毫秒)
[正常情况最好由服务器返回countdown字段,然后客户端再校对成该手机对应的时间,不然误差很大]
*/
private long endTime;
public ItemInfo(int id, String title, long countdown) {
this.id = id;
this.title = title;
this.countdown = countdown;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public long getCountdown() {
return countdown;
}
public void setCountdown(long countdown) {
this.countdown = countdown;
}
public long getEndTime() {
return endTime;
}
public void setEndTime(long endTime) {
this.endTime = endTime;
}
}
}
倒计时实现方案总结 Timer Handler的更多相关文章
- 倒计时 总结 Timer Handler CountDownTimer RxJava MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- java倒计时使用java.util.Timer实现,使用两个线程,以秒为单位
public class Countdown3 { private int lin; private int curSec; public Countdown3(int lin)throws Inte ...
- 115、定时器(TimerTask+Timer+Handler)
public class TimerUtils { public static Activity act; public static List<MaiDianModels> listMa ...
- jQuery简单倒计时插件
一. 效果预览 二. 实现 1. 按照特定的类结构布局. 2. 需要先引入jQuery,再引入此文件. /** * Author: CC11001100 * * 简单倒计时 * * 1. 支持页面内同 ...
- Kanzi编程基础1 - 定时器Timer
Kanzi虽然发生了比较多的版本更迭,api也发生了很多变化,但定时器的头文件一直都在一个地方:#include "user/include/user/ui/message/kzu_mess ...
- Handler使用总结(转)
方法一:(java习惯,在android平台开发时这样是不行的,因为它违背了单线程模型) 刚刚开始接触android线程编程的时候,习惯好像java一样,试图用下面的代码解决问题 new Thread ...
- android Timer使用方法
Timer属性:http://www.apihome.cn/api/java/Timer.html 声明创建: private Timer mTimer; protected void onCreat ...
- Android计数器的实现(倒计时)
安卓实现计数器有四种方式,直接给代码 1.使用Thread+Handler ; private Handler handler1 = new Handler() { @Override public ...
- Android之Handler,举例说明如何更新UI
方法一:(java习惯,在android不推荐使用) 刚刚开始接触android线程编程的时候,习惯好像java一样,试图用下面的代码解决问题 new Thread( new Runnable() { ...
随机推荐
- 见微知著(一):解析ctf中的pwn--Fast bin里的UAF
在网上关于ctf pwn的入门资料和writeup还是不少的,但是一些过渡的相关知识就比较少了,大部分赛棍都是在不断刷题中总结和进阶的.所以我觉得可以把学习过程中的遇到的一些问题和技巧总结成文,供大家 ...
- 详细介绍如何在Eclipse中使用SVN
一.在Eclipse中下载安装Subclipse插件 1 打开eclipse,在Help菜单中找到marketPlace,点击进入. 2 在搜索框Find中输入subclipse,点击右边的Go按 ...
- Web服务评估工具Nikto
Web服务评估工具Nikto Nikto是一款Perl语言编写的Web服务评估工具.该工具主要侧重于发现网站的默认配置和错误配置.它通过扫描的方式,检测服务器.服务和网站的配置文件,从中找出默认配 ...
- 一个人也可以建立 TCP 连接呢
今天(恰巧是今天)看到有人在 SegmentFault 上问「TCP server 为什么一个端口可以建立多个连接?」.提问者认为 client 端就不能使用相同的本地端口了.理论上来说,确定一条链路 ...
- 02-c#基础之01-基础语法(二)
1.变量的存储以及变量的几种类型 变量:用来在计算机当中存储数据. 存储变量的语法: 变量类型 变量名: 变量名=值: int number=100: 2.赋值"=" " ...
- Bzoj1018[SHOI2008]堵塞的交通traffic(线段树)
这题需要维护连通性,看到有连接删除,很容易直接就想LCT了.然而这题点数20w操作10w,LCT卡常估计过不去.看到这个东西只有两行,考虑能否用魔改后的线性数据结构去维护.我想到了线段树. 考虑如果两 ...
- java设计模式(四)代理模式
适用于为不同操作添加共同的额外行为.通过代理对象访问目标对象,这样可以增加对目标对象的额外操作,达到扩展目标对象功能的目的,如spring事务.AOP等. 要点:1)抽象角色:通过接口或抽象类声明真实 ...
- 拆分Cocos2dx渲染部分代码
纹理实现 思想 这个是Cocos2dx的渲染部分的最基本的实现,被我拆分到mac上,但是并不是用的EGLContext,而是搭配glfw,还有soil第三方图形库. 实现 // // main.cpp ...
- 安卓中WebKit的使用
1.在安卓开发中,使用webkit显示网页 步骤: ①初始化一个webkit控件: ②获取webkit的WebSettings对象: ③设置javascript为enable ④为webkit设置&q ...
- Codeforces Round #356 (Div. 1) D. Bear and Chase 暴力
D. Bear and Chase 题目连接: http://codeforces.com/contest/679/problem/D Description Bearland has n citie ...