没有合适的资源?快使用搜索试试~ 我知道了~
主要为大家详细介绍了Android多功能时钟开发案例,开发了时钟、闹钟、计时器和秒表,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
资源推荐
资源详情
资源评论
Android多功能时钟开发案例(实战篇)多功能时钟开发案例(实战篇)
主要为大家详细介绍了Android多功能时钟开发案例,开发了时钟、闹钟、计时器和秒表,具有一定的参考价
值,感兴趣的小伙伴们可以参考一下
上一篇为大家介绍的是Android多功能时钟开发基础内容,大家可以回顾一下,Android多功能时钟开发案例(基础篇)
接下来进入实战,快点来学习吧。
一、时钟一、时钟
在布局文件中我们看到,界面上只有一个TextView,这个TextView的作用就是显示一个系统的当前时间,同时这个时间还是
一秒一秒跳的,要实现一秒一秒的跳就需要我们每隔一秒就要刷新一下,同时我们这里还考虑了切换到另一个Tab的时候,这
个时间就不跳动了,这样就会减少这个对系统的占用,考虑到了这点我们在这里用到了Handler,通过handler发送的
msg.what 来判断是否要刷新时间。
public class TimeView extends LinearLayout {
private TextView tvTime;
public TimeView(Context context) {
super(context);
}
public TimeView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TimeView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
tvTime = (TextView) findViewById(R.id.tvTime);
//tvTime.setText("hello");
timeHandler.sendEmptyMessage(0);
}
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
//当再次切换到这个Tab时我们就再发送一次这个消息,否者就把所有的消息移除掉
if (visibility == View.VISIBLE) {
timeHandler.sendEmptyMessage(0);
}else{
timeHandler.removeMessages(0);
}
}
private void refreshTime(){
//获取当前的时间
Calendar c = Calendar.getInstance();
tvTime.setText(String.format("%d:%d:%d", c.get(Calendar.HOUR_OF_DAY),c.get(Calendar.MINUTE),c.get(Calendar.SECOND)));
}
private Handler timeHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
refreshTime();
//处于当前Tab的时候给自己发送信息,可以刷新
if (getVisibility() == View.VISIBLE) {
//1秒钟后再次执行以下sendEmptyMessage,what参数用于区分不同的message
timeHandler.sendEmptyMessageDelayed(0, 1000);
}
};
};
}
其实这里的Handler可以用Timer来完成亦可以达到同样的效果。
在这里要提一下的是onFinishInflate(),这在我们自定义布局的时候一定要用到的,解释以及例子在之后上传的知识点中同样
有,看看那个就可以了。
二、闹钟二、闹钟
从第二个布局中我们可以看到,我们在这里用到了一个ListView,这是用来存储我们添加的闹钟的,既然这里用到了
ListView,那么我们接着就会想到要给这个ListView一个适配器adapter,因此我们会在这里创建这么一个适配器,
private ArrayAdapter<AlarmData> adapter;
看到这里可能又会有疑问了,AlarmData这是个什么东西?有这么一个数据类型吗??其实这里我们自定义了一个数据类型,
用来专门存储一下创建的闹钟时间。我们来看一下自定义的数据类型代码吧!
// 自定义数据类型
private static class AlarmData {
private long time = 0;
private Calendar date;
private String timeLabel = "";
public AlarmData(long time) {
this.time = time;
date = Calendar.getInstance();
date.setTimeInMillis(time);
timeLabel = String.format("%d月%d日 %d:%d",
date.get(Calendar.MONTH) + 1,
date.get(Calendar.DAY_OF_MONTH),
date.get(Calendar.HOUR_OF_DAY), date.get(Calendar.MINUTE));
}
public long getTime() {
return time;
}
public String getTimeLabel() {
return timeLabel;
}
public int getId() {
return (int) (getTime() / 1000 / 60);
}
@Override
public String toString() {
return getTimeLabel();
}
}
这个数据类型的代码其实还是很容易明白的,不多讲了。
当我们到这里的时候,我们其实还没有真正的完成,假如我们的代码已经写好了,并且可以运行了我们运行一次后,并且添加
了N个闹钟,当我们退出程序,再次打开就会发现,我们之前创建的闹钟都没了,原因是我们虽然把数据临时的保存在了
ListView中,但是我们并没有长时间的保存,因此我们接着就来讲讲长久的保存这些闹钟数据。
private void saveAlarmList() {
Editor editor = getContext().getSharedPreferences(
AlarmView.class.getName(), Context.MODE_PRIVATE).edit();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < adapter.getCount(); i++) {
sb.append(adapter.getItem(i).getTime()).append(",");
}
if (sb.length() > 1) {
String content = sb.toString().substring(0, sb.length() - 1);
editor.putString(KEY_ALARM_LIST, content);
System.out.println(content);
} else {
editor.putString(KEY_ALARM_LIST, null);
}
editor.commit();
}
有了保存,我们当然的会想到读取
private void readSaveAlarmList() {
SharedPreferences sp = getContext().getSharedPreferences(
AlarmView.class.getName(), Context.MODE_PRIVATE);
String content = sp.getString(KEY_ALARM_LIST, null);
if (content != null) {
String[] timeStrings = content.split(",");
for (String string : timeStrings) {
adapter.add(new AlarmData(Long.parseLong(string)));
}
}
}
上面的一些陌生的类型在之后的知识点中可以查看。
接着我们来看看最关键的就是添加闹钟
private void addAlarm() {
Calendar c = Calendar.getInstance();
new TPDiolog(getContext(), new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
Calendar currentTime = Calendar.getInstance();
if (currentTime.getTimeInMillis() >= calendar.getTimeInMillis()) {
calendar.setTimeInMillis(calendar.getTimeInMillis() + 24
* 60 * 60 * 1000);
}
AlarmData ad = new AlarmData(calendar.getTimeInMillis());
adapter.add(ad);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
ad.getTime(), 5 * 60 * 1000, PendingIntent
.getBroadcast(getContext(), ad.getId(),
new Intent(getContext(),
AlarmReceiver.class), 0));
saveAlarmList();
}
}, c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), true).show();
}
这里我们可以看到TPDiolog这个,当你自己尝试过后可能也会遇到同样的问题,那就是当你通过TimePickerDialog这个系统的
时间选择控件的时候,点击确定后,会创建两条记录,这是因为我们点击确定后会调用该事件监听器的时间,在关闭这个
Dialog的时候也会调用一次,所以我们在这里自己重写了一下该类的方法
TPDiolog.class
public class TPDiolog extends TimePickerDialog {
public TPDiolog(Context context, OnTimeSetListener callBack, int hourOfDay,
int minute, boolean is24HourView) {
super(context, callBack, hourOfDay, minute, is24HourView);
}
//重写该方法是为了避免调用两次onTimeSet
@Override
protected void onStop() {
//super.onStop();
}
}
在之前的代码中我们还看到了一个alarmManager这一对象,这是我们为了调用系统的闹钟服务创建的实例,我们也因此而创
建了一个AlarmReceiver.class
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent arg1) {
System.out.println("闹钟执行了!");
AlarmManager am=(AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.cancel(PendingIntent.getBroadcast(context, getResultCode(), new Intent(context, AlarmReceiver.class), 0));
Intent i =new Intent(context,PlayAlarmAty.class);
//设置intent的启动模式
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
一些小的地方讲好了,最后把AlarmView.class的完整代码贴上。
package com.example.clock;
import java.util.Calendar;
import java.util.Date;
剩余11页未读,继续阅读
资源评论
weixin_38538950
- 粉丝: 4
- 资源: 930
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功