Android 倒计时(有效解决计时不准的问题)

本文介绍了Android倒计时可能存在的不准问题,并提出解决方案。通过设置未来某个时刻,每次显示倒计时差值,确保即使设备卡顿也能准确显示。同时讨论了在ListView中使用倒计时可能导致的控件问题,建议使用自定义View避免整体刷新影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看效果图

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();
	}

效果图








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值