一、闹钟功能的介绍以及界面的展示
该闹钟是根据我们手机闹钟设计的一个简单的闹钟APP,其中包含时钟、闹钟、秒表和计时器功能。用户可以对闹钟添加和删除,可以对秒表计时、暂停和重置,对计时器可以暂停、计时、继续和重置等功能。
二、介绍系统的设计界面
闹钟的布局文件代码如下
由于该闹钟系统包含时钟、闹钟、计时器、秒表四个功能,所以只要在xml文件插入TabHost控件就能实现在手机上更加简洁地展示四个功能。后面只需要在TabHost中插入四个Tab用来切换展示的界面,具体的代码实现如下:
public class MainActivity extends AppCompatActivity {
private TabHost mTabHost;
private StopWatchView mStopWatchView;
@Override
public SharedPreferences getPreferences(int mode) {
return super.getPreferences(mode);
}
@RequiresApi(api = Build.VERSION_CODES.P)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTabHost = (TabHost) findViewById(R.id.tabhost);
mTabHost.setup();
mTabHost.addTab(mTabHost.newTabSpec("tabTime").setIndicator("时钟").setContent(R.id.tabTime));
mTabHost.addTab(mTabHost.newTabSpec("tabAlarm").setIndicator("闹钟").setContent(R.id.tabAlarm));
mTabHost.addTab(mTabHost.newTabSpec("tabTimer").setIndicator("计时器").setContent(R.id.tabTimer));
mTabHost.addTab(mTabHost.newTabSpec("tabStopWatch").setIndicator("秒表").setContent(R.id.tabStopWatch));
mStopWatchView = (StopWatchView) findViewById(R.id.tabStopWatch);
}
@Override
protected void onDestroy() {
super.onDestroy();
mStopWatchView.onDestory();
}
}
一、时钟功能
因为时钟功能中,只要显示当前的日期和时钟就可以了,所以只需要插入一个TextView用来显示日期时间就可以了。
xml文件中的代码(new 一个时钟类TimeView,把时钟一块的LinearLayout换成com.example.tsclock.TimeView)
// 时钟
<com.example.tsclock.TimeView
android:id="@+id/tabTime"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tvTime"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:attr/textAppearanceLarge"
android:gravity="center"/>
</com.example.tsclock.TimeView>
TimeView.java
要将时间显示到TabHost中,就必须先要获取其中的id,然后通过Calendar获取当前系统的时间,最后再每过1秒钟刷新一次,这样就能够再TextView中出现时间在不停的变化。
public class TimeView extends LinearLayout {
private TextView tvTime;
public TimeView(Context context) {
super(context);
}
public TimeView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public TimeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
// 在初始化之后进行的操作
@Override
protected void onFinishInflate() {
super.onFinishInflate();
tvTime = (TextView) findViewById(R.id.tvTime);
// handler每秒执行一次
timerHandler.sendEmptyMessage(0);
}
// 可见属性发生变化之后
@Override
protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (visibility == View.VISIBLE){
// 如果可见 则发送一个消息
timerHandler.sendEmptyMessage(0);
}else{
// 如果不可见 移除所有的消息
timerHandler.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 timerHandler = new Handler() {
public void handleMessage(android.os.Message msg){
// 呈现出来
refreshTime();
// 如果可见 则刷新
if (getVisibility() == View.VISIBLE){
// 1000毫秒之后再制学校handlerMessage()方法
timerHandler.sendEmptyMessageDelayed(0,1000);
}
}
};
}
二、闹钟功能
闹钟功能就相对时钟功能就复杂很多了,因为这里需要对闹钟进行增加,删除等操作,而且可能需要展示多个闹钟的时间。所以这里需要用到有一个Button控件用来增加闹钟和一个ListView控件用来展示闹钟的时间。
xml代码
// 闹钟
<com.example.tsclock.AlarmView
android:id="@+id/tabAlarm"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/lvAlarmList"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp">
</ListView>
<Button
android:id="@+id/btnAddAlarm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/add_alarm"
android:textColor="#FFFFFF"
android:background="@color/colorBlue" />
</com.example.tsclock.AlarmView>
闹钟类,AlarmView.java
需要判断时间到了需要触发事件,需要播放音乐和震动。所以播放音乐和震动放在另一个活动中(PlayAlarmAty.java )
public class AlarmView extends LinearLayout {
private Button btnAddAlarm;
private ListView lvAlarmList;
private ArrayAdapter<AlarmData> mAdapter;
private static final String KEY_ALARM_LIST = "alarmList";
// 使用系统的闹钟服务
private AlarmManager mAlarmManager;
public AlarmView(Context context) {
super(context);
init();
}
public AlarmView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
private void init(){
// 使用闹钟服务设定闹钟
mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
}
// 在初始化之后进行的操作
@Override
protected void onFinishInflate() {
super.onFinishInflate();
btnAddAlarm = (Button)findViewById(R.id.btnAddAlarm);
lvAlarmList = (ListView) findViewById(R.id.lvAlarmList);
// 系统的简单资源
mAdapter = new ArrayAdapter<AlarmView.AlarmData>(getContext(),android.R.layout.simple_list_item_1);
// 设置Adapter
lvAlarmList.setAdapter(mAdapter);
// 读取已经存储在SharedPreferences中的数据
readSavedAlarmList();
btnAddAlarm.setOnClickListener(new View.OnClickListener() {
// 添加闹钟的点击事件
@Override
public void onClick(View v) {
addAlarm();
}
});
// 删除闹钟
lvAlarmList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,final int position, long id) {
new AlertDialog.Builder(getContext()).setTitle("操作选项").setItems(new CharSequence[]{
"删除"}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which){
case 0:
deleteAlarm(position);
break;
default:
break;
}
}
}).setNegativeButton("取消",null).show();
return true;
}
});
}
// 删除闹钟
private void deleteAlarm(int position){
AlarmData ad = mAdapter.getItem(position);
// 把闹钟从闹钟列表移除
mAdapter.remove(ad);
saveAlarmList();
// 移除闹钟
mAlarmManager.cancel(PendingIntent.getBroadcast(getContext(),ad.getId(),new Intent(getContext(),AlarmReceiver.class),0));
}
// 添加闹钟
private void addAlarm(){
// 获取当前时间
Calendar c = Calendar.getInstance();
// 弹出一个时间的选择框
new TimePickerDialog(getContext(), new TimePickerDialog.OnTimeSetListener() {
// 设置时间
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
// 获取当前时间
Calendar calendar = Calendar.getInstance();
calendar