Android 倒计时(有效解决计时不准的问题)
2015-10-20 15:45
639 查看
先看效果图
![](https://oscdn.geek-share.com/Uploads/Images/Content/202008/11/af33ab4525ef6cf3054c1ff666715f6b)
1,我采用的Handler延时 mHandler.sendEmptyMessageDelayed(1, 1000); 1000毫秒一次;
开始的时候 我想到的时 我要在20秒 开始倒计时 然后1000一次减1 如果倒计时的多了的话, 那就会不准。不是实际的20秒
1,后来,我想,当前时间是时刻变化的 也是准确的, 然后我给定他在未来的某个时刻。 每次Textview显示的时候都显示他们的差值,即使手机卡的用户 也不会因为卡而显示不正确。这对于某些抢购来说,时间显示很重要。
2, 也有的他也不确定未来的某个时刻。 就比如定时炸弹, 你在触发开关后的5分钟爆炸。 你就在触发开关那一刻 获取他的当前时间 然后加上5分钟。 然后去和每次的当前时间相减。
2, 还是把整个demo代码贴出来
3,bean 类
demo 下载地址 : http://download.csdn.net/detail/androidforme/9196905
后续补充:获取系统时间似乎是获取手机设置的时间。 而每个人的手机设置的时候不一样。所以,我想到的方案,是请求接口的时候,由服务器统一给出当前北京时间。
然而有不能每一秒都问服务器请求当前时间。 这样就要用的相对时间来处理。
服务器给的统一的北京时间 - 手机本机当前时间 = 相对时间 ;
手机本机当前时间 + 相对时间 = 北京时间。
这样有个相对时间 ,每次获取手机系统时间就能算出全国统一的时间。
2,后来发现在ListView 中, 时刻在刷新, 里面的控件 比如button 这样的,点击会出问题。 所以我们要只有这个显示时间的View 单独刷新。 这样就只能自定义View了。如何确保时间 还是采用之前的思路。
自定义View
public class TimeView extends View {
Paint mPaint; // 画笔,包含了画几何图形、文本等的样式和颜色信息
long a;
long sub;
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
invalidate();
};
};
public TimeView(Context context) {
super(context);
init();
}
public TimeView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TimeView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setColor(Color.RED); // 这里设置 画笔颜色
mPaint.setTextSize(24); // 字体大小
mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
mPaint.setTextAlign(Align.CENTER);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Date curDate = new Date(System.currentTimeMillis());// 获取当前时间
long cur = curDate.getTime();// 获取当前时间
canvas.drawText(time2time(a - (cur+sub)) , 50, 50, mPaint);// 用画笔在画布上添加文字,中间两个参数对应的是坐标。
mHandler.sendEmptyMessageDelayed(1, 100);
}
/**
* 剩余毫秒值 转换成 剩余时间格式
*
* @param t
* @return
*/
public String time2time(long t) {
if (t <= 0) {
return "00时:00分:00秒:000";
}
long haomiao = t % 1000;
long miao = t / 1000 % 60;
long min = t / 1000 / 60 % 60;
long h = t / 1000 / 60 / 60;
return h + "时:" + min + "分:" + String.format("%02d", miao) + "秒:"
+ String.format("%03d", haomiao);
}
/**
* yyyyMMddHHmmss 时间格式转毫秒值
*
* @param str
* @return
* @throws ParseException
*/
@SuppressLint("SimpleDateFormat")
public long time2millionSeconds(String str) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
long millionSeconds = sdf.parse(str).getTime();// 毫秒
return millionSeconds;
}
/**
*
* @param s 截止时间
* @param cur 服务器本地时间
* @throws ParseException
*/
public void setData(String s , String cur) throws ParseException {
a = time2millionSeconds(s);
Date curDate = new Date(System.currentTimeMillis());// 获取当前时间
long cur1 = curDate.getTime();// 获取当前时间
sub = time2millionSeconds(cur) -cur1;
}
在XML 使用。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.example.dadad.TimeView
android:id="@+id/s"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
调用
TimeView v = (TimeView) findViewById(R.id.s);
try {
v.setData("2015-10-27 18:23:01" ,"2015-10-27 18:21:01" );
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
效果图
1,我采用的Handler延时 mHandler.sendEmptyMessageDelayed(1, 1000); 1000毫秒一次;
开始的时候 我想到的时 我要在20秒 开始倒计时 然后1000一次减1 如果倒计时的多了的话, 那就会不准。不是实际的20秒
1,后来,我想,当前时间是时刻变化的 也是准确的, 然后我给定他在未来的某个时刻。 每次Textview显示的时候都显示他们的差值,即使手机卡的用户 也不会因为卡而显示不正确。这对于某些抢购来说,时间显示很重要。
2, 也有的他也不确定未来的某个时刻。 就比如定时炸弹, 你在触发开关后的5分钟爆炸。 你就在触发开关那一刻 获取他的当前时间 然后加上5分钟。 然后去和每次的当前时间相减。
</pre><pre name="code" class="java"> //这个是 字符串转毫秒值的方法
public long time2millionSeconds(String str) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); // <span style="color:#ff0000;">HH 要大写(24小时制的) 如果是小写的就是12小时制 </span> long millionSeconds = sdf.parse(str).getTime();// 毫秒 return millionSeconds; }
2, 还是把整个demo代码贴出来
public class MainActivity extends Activity { private List<Timebean> list; private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { adpater.notifyDataSetChanged(); mHandler.sendEmptyMessageDelayed(1, 10); }; }; private MyAdpater adpater; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); list = new ArrayList<Timebean>(); list.add(new Timebean("20151020151701")); // 这是2015年10月20日15时 17分 01秒 list.add(new Timebean("20151020151800")); list.add(new Timebean("20151020151900")); list.add(new Timebean("20151021120300")); list.add(new Timebean("20151021120400")); list.add(new Timebean("20151021120500")); list.add(new Timebean("20151021120600")); list.add(new Timebean("20151021120700")); GridView gv = (GridView) findViewById(R.id.gridview); adpater = new MyAdpater(); gv.setAdapter(adpater); mHandler.sendEmptyMessageDelayed(1, 1); } class MyAdpater extends BaseAdapter { public int getCount() { // TODO Auto-generated method stub return list.size(); } public Object getItem(int position) { // TODO Auto-generated method stub return null; } public long getItemId(int position) { // TODO Auto-generated method stub return 0; } public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = LayoutInflater.from(parent.getContext()).inflate( R.layout.ddddddd, null); } TextView tv = (TextView) convertView.findViewById(R.id.tv); Timebean time = list.get(position); Date curDate = new Date(System.currentTimeMillis());// 获取当前时间 long cur = curDate.getTime(); long t; try { t = time2millionSeconds(time.a); String ts = time2time(t - cur); tv.setText(ts); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } return convertView; } } public String time2time(long t) { if (t<= 0) { return "00时:00分:00秒:000"; } long haomiao = t % 1000; long miao = t / 1000 % 60; long min = t / 1000 / 60 % 60; long h = t / 1000 / 60 / 60; return h + "时:" + min + "分:" + String.format("%02d", miao) + "秒:" + String.format("%03d", haomiao); } @SuppressLint("SimpleDateFormat") public long time2millionSeconds(String str) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); long millionSeconds = sdf.parse(str).getTime();// 毫秒 return millionSeconds; } }
3,bean 类
public class Timebean { String a ; public Timebean(String a) { super(); this.a = a; } }
demo 下载地址 : http://download.csdn.net/detail/androidforme/9196905
后续补充:获取系统时间似乎是获取手机设置的时间。 而每个人的手机设置的时候不一样。所以,我想到的方案,是请求接口的时候,由服务器统一给出当前北京时间。
然而有不能每一秒都问服务器请求当前时间。 这样就要用的相对时间来处理。
服务器给的统一的北京时间 - 手机本机当前时间 = 相对时间 ;
手机本机当前时间 + 相对时间 = 北京时间。
这样有个相对时间 ,每次获取手机系统时间就能算出全国统一的时间。
2,后来发现在ListView 中, 时刻在刷新, 里面的控件 比如button 这样的,点击会出问题。 所以我们要只有这个显示时间的View 单独刷新。 这样就只能自定义View了。如何确保时间 还是采用之前的思路。
自定义View
public class TimeView extends View {
Paint mPaint; // 画笔,包含了画几何图形、文本等的样式和颜色信息
long a;
long sub;
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
invalidate();
};
};
public TimeView(Context context) {
super(context);
init();
}
public TimeView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TimeView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setColor(Color.RED); // 这里设置 画笔颜色
mPaint.setTextSize(24); // 字体大小
mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
mPaint.setTextAlign(Align.CENTER);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Date curDate = new Date(System.currentTimeMillis());// 获取当前时间
long cur = curDate.getTime();// 获取当前时间
canvas.drawText(time2time(a - (cur+sub)) , 50, 50, mPaint);// 用画笔在画布上添加文字,中间两个参数对应的是坐标。
mHandler.sendEmptyMessageDelayed(1, 100);
}
/**
* 剩余毫秒值 转换成 剩余时间格式
*
* @param t
* @return
*/
public String time2time(long t) {
if (t <= 0) {
return "00时:00分:00秒:000";
}
long haomiao = t % 1000;
long miao = t / 1000 % 60;
long min = t / 1000 / 60 % 60;
long h = t / 1000 / 60 / 60;
return h + "时:" + min + "分:" + String.format("%02d", miao) + "秒:"
+ String.format("%03d", haomiao);
}
/**
* yyyyMMddHHmmss 时间格式转毫秒值
*
* @param str
* @return
* @throws ParseException
*/
@SuppressLint("SimpleDateFormat")
public long time2millionSeconds(String str) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
long millionSeconds = sdf.parse(str).getTime();// 毫秒
return millionSeconds;
}
/**
*
* @param s 截止时间
* @param cur 服务器本地时间
* @throws ParseException
*/
public void setData(String s , String cur) throws ParseException {
a = time2millionSeconds(s);
Date curDate = new Date(System.currentTimeMillis());// 获取当前时间
long cur1 = curDate.getTime();// 获取当前时间
sub = time2millionSeconds(cur) -cur1;
}
在XML 使用。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.example.dadad.TimeView
android:id="@+id/s"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
调用
TimeView v = (TimeView) findViewById(R.id.s);
try {
v.setData("2015-10-27 18:23:01" ,"2015-10-27 18:21:01" );
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
效果图
相关文章推荐
- Android高手必学个性化控件之ImageView
- ServiceManager守护进程的注册
- android CTS/GTS---常用测试命令
- Android在代码中设置textview字体颜色
- Android - Glide的使用
- android ListView向下展开 抽屉效果
- Android 导入项目中R文件丢失
- Android -- Looper.prepare()和Looper.loop() —深入版
- Android Studio debug使用release的签名
- Paho
- 了解Android中的接口回调机制
- Android-ActionBar
- 学习Android推送功能笔记(1)
- Android 之 内存管理
- android 使用AndroidAnnotations注解简化安卓开发
- 一个常用的布局技巧
- Android 默认把触摸屏show touches打开
- Android Activity回穿值总结
- Android 监听scrollview滚动实现ToolBar显示和隐藏的效果
- 如何解决android模拟器慢的问题