Android多功能時(shí)鐘開(kāi)發(fā)案例(實(shí)戰(zhàn)篇)
上一篇為大家介紹的是Android多功能時(shí)鐘開(kāi)發(fā)基礎(chǔ)內(nèi)容,大家可以回顧一下,Android多功能時(shí)鐘開(kāi)發(fā)案例(基礎(chǔ)篇)
接下來(lái)進(jìn)入實(shí)戰(zhàn),快點(diǎn)來(lái)學(xué)習(xí)吧。
一、時(shí)鐘
在布局文件中我們看到,界面上只有一個(gè)TextView,這個(gè)TextView的作用就是顯示一個(gè)系統(tǒng)的當(dāng)前時(shí)間,同時(shí)這個(gè)時(shí)間還是一秒一秒跳的,要實(shí)現(xiàn)一秒一秒的跳就需要我們每隔一秒就要刷新一下,同時(shí)我們這里還考慮了切換到另一個(gè)Tab的時(shí)候,這個(gè)時(shí)間就不跳動(dòng)了,這樣就會(huì)減少這個(gè)對(duì)系統(tǒng)的占用,考慮到了這點(diǎn)我們?cè)谶@里用到了Handler,通過(guò)handler發(fā)送的msg.what 來(lái)判斷是否要刷新時(shí)間。
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);
//當(dāng)再次切換到這個(gè)Tab時(shí)我們就再發(fā)送一次這個(gè)消息,否者就把所有的消息移除掉
if (visibility == View.VISIBLE) {
timeHandler.sendEmptyMessage(0);
}else{
timeHandler.removeMessages(0);
}
}
private void refreshTime(){
//獲取當(dāng)前的時(shí)間
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();
//處于當(dāng)前Tab的時(shí)候給自己發(fā)送信息,可以刷新
if (getVisibility() == View.VISIBLE) {
//1秒鐘后再次執(zhí)行以下sendEmptyMessage,what參數(shù)用于區(qū)分不同的message
timeHandler.sendEmptyMessageDelayed(0, 1000);
}
};
};
}
其實(shí)這里的Handler可以用Timer來(lái)完成亦可以達(dá)到同樣的效果。
在這里要提一下的是onFinishInflate(),這在我們自定義布局的時(shí)候一定要用到的,解釋以及例子在之后上傳的知識(shí)點(diǎn)中同樣有,看看那個(gè)就可以了。
二、鬧鐘
從第二個(gè)布局中我們可以看到,我們?cè)谶@里用到了一個(gè)ListView,這是用來(lái)存儲(chǔ)我們添加的鬧鐘的,既然這里用到了ListView,那么我們接著就會(huì)想到要給這個(gè)ListView一個(gè)適配器adapter,因此我們會(huì)在這里創(chuàng)建這么一個(gè)適配器,
private ArrayAdapter<AlarmData> adapter;
看到這里可能又會(huì)有疑問(wèn)了,AlarmData這是個(gè)什么東西?有這么一個(gè)數(shù)據(jù)類型嗎??其實(shí)這里我們自定義了一個(gè)數(shù)據(jù)類型,用來(lái)專門(mén)存儲(chǔ)一下創(chuàng)建的鬧鐘時(shí)間。我們來(lái)看一下自定義的數(shù)據(jù)類型代碼吧!
// 自定義數(shù)據(jù)類型
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();
}
}
這個(gè)數(shù)據(jù)類型的代碼其實(shí)還是很容易明白的,不多講了。
當(dāng)我們到這里的時(shí)候,我們其實(shí)還沒(méi)有真正的完成,假如我們的代碼已經(jīng)寫(xiě)好了,并且可以運(yùn)行了我們運(yùn)行一次后,并且添加了N個(gè)鬧鐘,當(dāng)我們退出程序,再次打開(kāi)就會(huì)發(fā)現(xiàn),我們之前創(chuàng)建的鬧鐘都沒(méi)了,原因是我們雖然把數(shù)據(jù)臨時(shí)的保存在了ListView中,但是我們并沒(méi)有長(zhǎng)時(shí)間的保存,因此我們接著就來(lái)講講長(zhǎng)久的保存這些鬧鐘數(shù)據(jù)。
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();
}
有了保存,我們當(dāng)然的會(huì)想到讀取
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)));
}
}
}
上面的一些陌生的類型在之后的知識(shí)點(diǎn)中可以查看。
接著我們來(lái)看看最關(guān)鍵的就是添加鬧鐘
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這個(gè),當(dāng)你自己嘗試過(guò)后可能也會(huì)遇到同樣的問(wèn)題,那就是當(dāng)你通過(guò)TimePickerDialog這個(gè)系統(tǒng)的時(shí)間選擇控件的時(shí)候,點(diǎn)擊確定后,會(huì)創(chuàng)建兩條記錄,這是因?yàn)槲覀凕c(diǎn)擊確定后會(huì)調(diào)用該事件監(jiān)聽(tīng)器的時(shí)間,在關(guān)閉這個(gè)Dialog的時(shí)候也會(huì)調(diào)用一次,所以我們?cè)谶@里自己重寫(xiě)了一下該類的方法
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);
}
//重寫(xiě)該方法是為了避免調(diào)用兩次onTimeSet
@Override
protected void onStop() {
//super.onStop();
}
}
在之前的代碼中我們還看到了一個(gè)alarmManager這一對(duì)象,這是我們?yōu)榱苏{(diào)用系統(tǒng)的鬧鐘服務(wù)創(chuàng)建的實(shí)例,我們也因此而創(chuàng)建了一個(gè)AlarmReceiver.class
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent arg1) {
System.out.println("鬧鐘執(zhí)行了!");
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);
//設(shè)置intent的啟動(dòng)模式
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
一些小的地方講好了,最后把AlarmView.class的完整代碼貼上。
package com.example.clock;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Switch;
import android.widget.TimePicker;
public class AlarmView extends LinearLayout {
private Button btnAddAlarm;
private ListView lvListAlarm;
private ArrayAdapter<AlarmData> adapter;
private AlarmManager alarmManager;
public AlarmView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public AlarmView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public AlarmView(Context context) {
super(context);
init();
}
private void init() {
alarmManager = (AlarmManager) getContext().getSystemService(
Context.ALARM_SERVICE);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
btnAddAlarm = (Button) findViewById(R.id.btnAddAlarm);
lvListAlarm = (ListView) findViewById(R.id.lvListAlarm);
adapter = new ArrayAdapter<AlarmData>(getContext(),
android.R.layout.simple_list_item_1);
lvListAlarm.setAdapter(adapter);
readSaveAlarmList();
// adapter.add(new AlarmData(System.currentTimeMillis()));
btnAddAlarm.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
addAlarm();
}
});
// 長(zhǎng)按某項(xiàng)刪除
lvListAlarm.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
final int position, long arg3) {
new AlertDialog.Builder(getContext())
.setTitle("操作選項(xiàng)")
.setItems(new CharSequence[] { "刪除", "刪除1" },
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 = adapter.getItem(position);
adapter.remove(ad);
saveAlarmList();
alarmManager.cancel(PendingIntent.getBroadcast(getContext(),
ad.getId(), new Intent(getContext(), AlarmReceiver.class), 0));
}
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();
}
private static final String KEY_ALARM_LIST = "alarmlist";
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)));
}
}
}
// 自定義數(shù)據(jù)類型
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();
}
}
}
三、計(jì)時(shí)器
計(jì)時(shí)器的主要功能就是你先設(shè)定一個(gè)時(shí)間,然后點(diǎn)擊開(kāi)始,時(shí)間就會(huì)一秒一秒的減少,在這里我么主要用到了Timer這個(gè)系統(tǒng)的計(jì)時(shí)器,這代碼中沒(méi)有上面難懂的地方,有些地方已經(jīng)給上注釋了,所以直接貼代碼,可能有些人會(huì)不知道Timer怎么用,之后的知識(shí)點(diǎn)中都會(huì)有提到。
package com.example.clock;
import java.util.Timer;
import java.util.TimerTask;
import android.R.integer;
import android.app.AlertDialog;
import android.content.Context;
import android.os.Handler;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
public class TimerView extends LinearLayout {
public TimerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TimerView(Context context) {
super(context);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
btnStart = (Button) findViewById(R.id.btnStart);
btnPause = (Button) findViewById(R.id.btnPause);
btnResume = (Button) findViewById(R.id.btnResume);
btnReset = (Button) findViewById(R.id.btnReset);
btnStart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startTimer();
btnStart.setVisibility(View.GONE);
btnPause.setVisibility(View.VISIBLE);
btnReset.setVisibility(View.VISIBLE);
}
});
btnPause.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
stopTimer();
btnPause.setVisibility(View.GONE);
btnResume.setVisibility(View.VISIBLE);
}
});
btnResume.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startTimer();
btnPause.setVisibility(View.VISIBLE);
btnResume.setVisibility(View.GONE);
}
});
btnReset.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
stopTimer();
etHour.setText("00");
etMin.setText("00");
etSec.setText("00");
btnReset.setVisibility(View.GONE);
btnResume.setVisibility(View.GONE);
btnPause.setVisibility(View.GONE);
btnStart.setVisibility(View.VISIBLE);
}
});
etHour = (EditText) findViewById(R.id.etHour);
etMin = (EditText) findViewById(R.id.etMin);
etSec = (EditText) findViewById(R.id.etSec);
etHour.setText("00");
etHour.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
/*
* 這個(gè)方法是在Text改變過(guò)程中觸發(fā)調(diào)用的, 它的意思就是說(shuō)在原有的文本s中,
* 從start開(kāi)始的count個(gè)字符替換長(zhǎng)度為before的舊文本,
* 注意這里沒(méi)有將要之類的字眼,也就是說(shuō)一句執(zhí)行了替換動(dòng)作。
*/
if (!TextUtils.isEmpty(s)) {
int value = Integer.parseInt(s.toString());
if (value > 59) {
etHour.setText("59");
} else if (value < 0) {
etHour.setText("00");
}
}
checkToEnableBtnStart();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
etMin.setText("00");
etMin.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (!TextUtils.isEmpty(s)) {
int value = Integer.parseInt(s.toString());
if (value > 59) {
etMin.setText("59");
} else if (value < 0) {
etMin.setText("00");
}
}
checkToEnableBtnStart();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
etSec.setText("00");
etSec.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (!TextUtils.isEmpty(s)) {
int value = Integer.parseInt(s.toString());
if (value > 59) {
etSec.setText("59");
} else if (value < 0) {
etSec.setText("00");
}
}
checkToEnableBtnStart();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
btnStart.setVisibility(View.VISIBLE);
btnStart.setEnabled(false);
btnPause.setVisibility(View.GONE);
btnResume.setVisibility(View.GONE);
btnReset.setVisibility(View.GONE);
}
private void checkToEnableBtnStart() {
btnStart.setEnabled((!TextUtils.isEmpty(etHour.getText()) && Integer
.parseInt(etHour.getText().toString()) > 0)
|| (!TextUtils.isEmpty(etMin.getText()) && Integer
.parseInt(etMin.getText().toString()) > 0)
|| (!TextUtils.isEmpty(etSec.getText()) && Integer
.parseInt(etSec.getText().toString()) > 0));
}
private void startTimer() {
if (timerTask == null) {
allTimeCount = Integer.parseInt(etHour.getText().toString()) * 60
* 60 + Integer.parseInt(etMin.getText().toString()) * 60
+ Integer.parseInt(etSec.getText().toString());
timerTask = new TimerTask() {
@Override
public void run() {
allTimeCount--;
handle.sendEmptyMessage(MSG_WHAT_TIME_TICK);
if (allTimeCount <= 0) {
handle.sendEmptyMessage(MSG_WHAT_TIME_IS_UP);
stopTimer();
}
}
};
timer.schedule(timerTask, 1000, 1000);
}
}
private void stopTimer(){
if (timerTask!=null) {
timerTask.cancel();
timerTask=null;
}
}
private Handler handle = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case MSG_WHAT_TIME_TICK:
int hour = allTimeCount/60/60;
int min = (allTimeCount/60)%60;
int sec = allTimeCount%60;
etHour.setText(hour+"");
etMin.setText(min+"");
etSec.setText(sec+"");
break;
case MSG_WHAT_TIME_IS_UP:
new AlertDialog.Builder(getContext())
.setTitle("Time is up!")
.setMessage("Time is up!")
.setNegativeButton("Cancle", null).show();
btnReset.setVisibility(View.GONE);
btnResume.setVisibility(View.GONE);
btnPause.setVisibility(View.GONE);
btnStart.setVisibility(View.VISIBLE);
break;
default:
break;
}
};
};
private static final int MSG_WHAT_TIME_IS_UP = 1;
private static final int MSG_WHAT_TIME_TICK = 2;
private int allTimeCount = 0;
private Timer timer = new Timer();
private TimerTask timerTask = null;
private Button btnStart, btnPause, btnResume, btnReset;
private EditText etHour, etMin, etSec;
}
四、秒表
最后的秒表相信大家都不陌生,用到的知識(shí)正好之前的三個(gè)都有講到,只要明白前三個(gè)后,這個(gè)就不難理解了。
package com.example.clock;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
public class StopWatchView extends LinearLayout {
private TextView tvHour,tvMin,tvSec,tvMsec;
private Button btnStart,btnPause,btnResume,btnReset,btnLap;
private ListView lvTimeList;
private ArrayAdapter<String> adapter;
public StopWatchView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
tvHour = (TextView) findViewById(R.id.timeHour);
tvHour.setText("0");
tvMin = (TextView) findViewById(R.id.timeMin);
tvMin.setText("0");
tvSec = (TextView) findViewById(R.id.timeSec);
tvSec.setText("0");
tvMsec = (TextView) findViewById(R.id.timeMsec);
tvMsec.setText("0");
btnStart = (Button) findViewById(R.id.btnSWStart);
btnPause = (Button) findViewById(R.id.btnSWPause);
btnResume = (Button) findViewById(R.id.btnSWResume);
btnLap = (Button) findViewById(R.id.btnSWLap);
btnReset = (Button) findViewById(R.id.btnSWReset);
btnStart.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startTimer();
btnStart.setVisibility(View.GONE);
btnPause.setVisibility(View.VISIBLE);
btnLap.setVisibility(View.VISIBLE);
}
});
btnPause.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
stopTimer();
btnPause.setVisibility(View.GONE);
btnResume.setVisibility(View.VISIBLE);
btnLap.setVisibility(View.GONE);
btnReset.setVisibility(View.VISIBLE);
}
});
btnResume.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startTimer();
btnResume.setVisibility(View.GONE);
btnPause.setVisibility(View.VISIBLE);
btnLap.setVisibility(View.VISIBLE);
btnReset.setVisibility(View.GONE);
}
});
btnReset.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
stopTimer();
tenMSecs = 0;
adapter.clear();
btnReset.setVisibility(View.GONE);
btnLap.setVisibility(View.GONE);
btnPause.setVisibility(View.GONE);
btnResume.setVisibility(View.GONE);
btnStart.setVisibility(View.VISIBLE);
}
});
btnLap.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
adapter.insert(String.format("%d:%d:%d.%d", tenMSecs/100/60/60,tenMSecs/100/60%60,tenMSecs/100%60,tenMSecs%100), 0);
}
});
btnLap.setVisibility(View.GONE);
btnPause.setVisibility(View.GONE);
btnResume.setVisibility(View.GONE);
btnReset.setVisibility(View.GONE);
lvTimeList = (ListView) findViewById(R.id.lvWatchTime);
adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1);
lvTimeList.setAdapter(adapter);
showTimerTask = new TimerTask() {
@Override
public void run() {
handle.sendEmptyMessage(MSG_WHAT_SHOW_TIME);
}
};
timer.schedule(showTimerTask, 200, 200);
}
private void startTimer(){
if (timerTask == null) {
timerTask = new TimerTask() {
@Override
public void run() {
tenMSecs++;
}
};
timer.schedule(timerTask, 10, 10);
}
}
private void stopTimer(){
if (timerTask != null) {
timerTask.cancel();
timerTask = null;
}
}
private int tenMSecs = 0;
private Timer timer =new Timer();
private TimerTask timerTask = null;
private TimerTask showTimerTask = null;
private static final int MSG_WHAT_SHOW_TIME = 1;
private Handler handle = new Handler(){
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case MSG_WHAT_SHOW_TIME:
tvHour.setText(tenMSecs/100/60/60+"");
tvMin.setText(tenMSecs/100/60%60+"");
tvSec.setText(tenMSecs/100%60+"");
tvMsec.setText(tenMSecs%100+"");
break;
default:
break;
}
};
};
public void onDestroy() {
timer.cancel();
}
}
到此為止,自己的第一個(gè)實(shí)戰(zhàn)算是完成了,但是就是界面很low,這個(gè)只是把基本的功能實(shí)現(xiàn)了,但是在界面上沒(méi)有做很大的完善,在之后的實(shí)戰(zhàn)中會(huì)慢慢改進(jìn)的。
源碼下載:Android多功能時(shí)鐘
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android獲取設(shè)備CPU核數(shù)、時(shí)鐘頻率以及內(nèi)存大小的方法
- android實(shí)現(xiàn)widget時(shí)鐘示例分享
- Android 仿日歷翻頁(yè)、仿htc時(shí)鐘翻頁(yè)、數(shù)字翻頁(yè)切換效果
- Android多功能時(shí)鐘開(kāi)發(fā)案例(基礎(chǔ)篇)
- android高仿小米時(shí)鐘(使用Camera和Matrix實(shí)現(xiàn)3D效果)
- Android實(shí)現(xiàn)簡(jiǎn)單時(shí)鐘View的方法
- Android自定義動(dòng)態(tài)壁紙開(kāi)發(fā)(時(shí)鐘)
- Android編程基于自定義控件實(shí)現(xiàn)時(shí)鐘功能的方法
- Android仿小米時(shí)鐘效果
- Android自定義View實(shí)現(xiàn)時(shí)鐘功能
相關(guān)文章
Android富文本實(shí)現(xiàn)的幾種方式匯總
由于項(xiàng)目中需要使用到富文本顯示和編輯,索性整理下,這篇文章主要給大家介紹了關(guān)于Android富文本實(shí)現(xiàn)的幾種方式,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
Android手勢(shì)ImageView三部曲 第一部
這篇文章主要為大家詳細(xì)介紹了Android手勢(shì)ImageView三部曲的第一部,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
Android進(jìn)程間通信(IPC)機(jī)制Binder簡(jiǎn)要介紹
本文主要介紹 Android進(jìn)程間通信(IPC)機(jī)制Binder簡(jiǎn)要介紹, 這里介紹了Binder機(jī)制如何實(shí)現(xiàn)進(jìn)程通信機(jī)制,有研究Android源碼的朋友可以看下2016-08-08
Android中使用imageviewswitcher 實(shí)現(xiàn)圖片切換輪播導(dǎo)航的方法
ImageSwitcher是Android中控制圖片展示效果的一個(gè)控件。本文給大家介紹Android中使用imageviewswitcher 實(shí)現(xiàn)圖片切換輪播導(dǎo)航的方法,需要的朋友參考下吧2016-12-12
Android框架學(xué)習(xí)之Volley和Glide詳解
這篇文章主要給大家介紹了關(guān)于Android框架學(xué)習(xí)之Volley和Glide的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位Android開(kāi)發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05
android實(shí)現(xiàn)簡(jiǎn)易登錄注冊(cè)界面及邏輯設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)簡(jiǎn)易登錄注冊(cè)界面及邏輯設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
關(guān)于Android bitmap你不知道的一些事
這篇文章主要為大家詳細(xì)介紹了關(guān)于Android bitmap你不知道的一些事,使用bitmap需要注意的一些細(xì)節(jié),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11

