您的位置:首页 > 移动开发 > Android开发

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

2015-10-20 15:45 639 查看
先看效果图



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

效果图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: