Android開發(fā)實(shí)戰(zhàn)鬧鐘項(xiàng)目
本文實(shí)例為大家分享了Android實(shí)戰(zhàn)鬧鐘項(xiàng)目的具體代碼,供大家參考,具體內(nèi)容如下
一、鬧鐘功能的介紹以及界面的展示
該鬧鐘是根據(jù)我們手機(jī)鬧鐘設(shè)計(jì)的一個(gè)簡單的鬧鐘APP,其中包含時(shí)鐘、鬧鐘、秒表和計(jì)時(shí)器功能。用戶可以對鬧鐘添加和刪除,可以對秒表計(jì)時(shí)、暫停和重置,對計(jì)時(shí)器可以暫停、計(jì)時(shí)、繼續(xù)和重置等功能。
二、介紹系統(tǒng)的設(shè)計(jì)界面
鬧鐘的布局文件代碼如下
由于該鬧鐘系統(tǒng)包含時(shí)鐘、鬧鐘、計(jì)時(shí)器、秒表四個(gè)功能,所以只要在xml文件插入TabHost控件就能實(shí)現(xiàn)在手機(jī)上更加簡潔地展示四個(gè)功能。后面只需要在TabHost中插入四個(gè)Tab用來切換展示的界面,具體的代碼實(shí)現(xiàn)如下:
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("時(shí)鐘").setContent(R.id.tabTime)); ? ? ? ? mTabHost.addTab(mTabHost.newTabSpec("tabAlarm").setIndicator("鬧鐘").setContent(R.id.tabAlarm)); ? ? ? ? mTabHost.addTab(mTabHost.newTabSpec("tabTimer").setIndicator("計(jì)時(shí)器").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(); ? ? } }
一、時(shí)鐘功能
因?yàn)闀r(shí)鐘功能中,只要顯示當(dāng)前的日期和時(shí)鐘就可以了,所以只需要插入一個(gè)TextView用來顯示日期時(shí)間就可以了。
xml文件中的代碼(new 一個(gè)時(shí)鐘類TimeView,把時(shí)鐘一塊的LinearLayout換成com.example.tsclock.TimeView)
?// 時(shí)鐘 <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
要將時(shí)間顯示到TabHost中,就必須先要獲取其中的id,然后通過Calendar獲取當(dāng)前系統(tǒng)的時(shí)間,最后再每過1秒鐘刷新一次,這樣就能夠再TextView中出現(xiàn)時(shí)間在不停的變化。
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); ? ? } ? ? // 在初始化之后進(jìn)行的操作 ? ? @Override ? ? protected void onFinishInflate() { ? ? ? ? super.onFinishInflate(); ? ? ? ? tvTime = (TextView) findViewById(R.id.tvTime); ? ? ? ? // handler每秒執(zhí)行一次 ? ? ? ? timerHandler.sendEmptyMessage(0); ? ? } ? ? // 可見屬性發(fā)生變化之后 ? ? @Override ? ? protected void onVisibilityChanged(@NonNull View changedView, int visibility) { ? ? ? ? super.onVisibilityChanged(changedView, visibility); ? ? ? ? if (visibility == View.VISIBLE){ // 如果可見 則發(fā)送一個(gè)消息 ? ? ? ? ? ? timerHandler.sendEmptyMessage(0); ? ? ? ? }else{ ? ? ? ? ? ? ? ? ? ? ? ? ? // ?如果不可見 移除所有的消息 ? ? ? ? ? ? timerHandler.removeMessages(0); ? ? ? ? } ? ? } ? ? // 重新刷新時(shí)間 ? ? private void refreshTime(){ ? ? ? ? // 呈現(xiàn)一個(gè)時(shí)間對象 ? ? ? ? Calendar c = Calendar.getInstance(); ? ? ? ? // 獲取時(shí)分秒 ? ? ? ? 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){ ? ? ? ? ? ? // 呈現(xiàn)出來 ? ? ? ? ? ? refreshTime(); ? ? ? ? ? ? // 如果可見 則刷新 ? ? ? ? ? ? if (getVisibility() == View.VISIBLE){ ? ? ? ? ? ? ? ? // 1000毫秒之后再制學(xué)校handlerMessage()方法 ? ? ? ? ? ? ? ? timerHandler.sendEmptyMessageDelayed(0,1000); ? ? ? ? ? ? } ? ? ? ? } ? ? }; }
二、鬧鐘功能
鬧鐘功能就相對時(shí)鐘功能就復(fù)雜很多了,因?yàn)檫@里需要對鬧鐘進(jìn)行增加,刪除等操作,而且可能需要展示多個(gè)鬧鐘的時(shí)間。所以這里需要用到有一個(gè)Button控件用來增加鬧鐘和一個(gè)ListView控件用來展示鬧鐘的時(shí)間。
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
需要判斷時(shí)間到了需要觸發(fā)事件,需要播放音樂和震動(dòng)。所以播放音樂和震動(dòng)放在另一個(gè)活動(dòng)中(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"; ? ? // 使用系統(tǒng)的鬧鐘服務(wù) ? ? private AlarmManager mAlarmManager; ? ? public AlarmView(Context context) { ? ? ? ? super(context); ? ? ? ? init(); ? ? } ? ? public AlarmView(Context context, @Nullable AttributeSet attrs) { ? ? ? ? super(context, attrs); ? ? ? ? init(); ? ? } ? ? private void init(){ ? ? ? ? // 使用鬧鐘服務(wù)設(shè)定鬧鐘 ? ? ? ? mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); ? ? } ? ? // 在初始化之后進(jìn)行的操作 ? ? @Override ? ? protected void onFinishInflate() { ? ? ? ? super.onFinishInflate(); ? ? ? ? btnAddAlarm ?= (Button)findViewById(R.id.btnAddAlarm); ? ? ? ? lvAlarmList = (ListView) findViewById(R.id.lvAlarmList); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 系統(tǒng)的簡單資源 ? ? ? ? mAdapter = new ArrayAdapter<AlarmView.AlarmData>(getContext(),android.R.layout.simple_list_item_1); ? ? ? ? // 設(shè)置Adapter ? ? ? ? lvAlarmList.setAdapter(mAdapter); ? ? ? ? // 讀取已經(jīng)存儲(chǔ)在SharedPreferences中的數(shù)據(jù) ? ? ? ? readSavedAlarmList(); ? ? ? ? btnAddAlarm.setOnClickListener(new View.OnClickListener() {// 添加鬧鐘的點(diǎn)擊事件 ? ? ? ? ? ? @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("操作選項(xiàng)").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(){ ? ? ? ? // 獲取當(dāng)前時(shí)間 ? ? ? ? Calendar c = Calendar.getInstance(); ? ? ? ? // 彈出一個(gè)時(shí)間的選擇框 ? ? ? ? new TimePickerDialog(getContext(), new TimePickerDialog.OnTimeSetListener() { ? ? ? ? ? ? // 設(shè)置時(shí)間 ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onTimeSet(TimePicker view, int hourOfDay, int minute) { ? ? ? ? ? ? ? ? // 獲取當(dāng)前時(shí)間 ? ? ? ? ? ? ? ? Calendar calendar = Calendar.getInstance(); ? ? ? ? ? ? ? ? calendar.set(Calendar.HOUR_OF_DAY,hourOfDay); // 設(shè)置時(shí) ? ? ? ? ? ? ? ? calendar.set(Calendar.MINUTE,minute); ? // 設(shè)置分鐘 ? ? ? ? ? ? ? ? calendar.set(Calendar.SECOND,0); ?// 秒清零 ? ? ? ? ? ? ? ? calendar.set(Calendar.MILLISECOND,0); // 毫秒值清零 ? ? ? ? ? ? ? ? // 如果設(shè)置鬧鐘時(shí)間小于當(dāng)前時(shí)間,則往后推一天 ? ? ? ? ? ? ? ? Calendar currentTime = Calendar.getInstance(); ? ? ? ? ? ? ? ? if (calendar.getTimeInMillis() <= currentTime.getTimeInMillis()){ ? ? ? ? ? ? ? ? ? ? calendar.setTimeInMillis(calendar.getTimeInMillis()+24*60*60*1000); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? AlarmData ad = new AlarmData(calendar.getTimeInMillis()); ? ? ? ? ? ? ? ? mAdapter.add(ad); ? ? ? ? ? ? ? ? //需要根據(jù)API版本來判斷調(diào)用,從Android4.4(API19)開始,為了節(jié)能省電(減少系統(tǒng)喚醒和電池使用) ? ? ? ? ? ? ? ? if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { ? ? ? ? ? ? ? ? ? ? mAlarmManager.setWindow(AlarmManager.RTC_WAKEUP, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ad.getTime(), ? ? ? ? ? ? ? ? ? ? ? ? ? ? 100, // 時(shí)間誤差范圍 100毫秒 ? ? ? ? ? ? ? ? ? ? ? ? ? ? PendingIntent.getBroadcast(getContext(), ad.getId(), ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new Intent(getContext(), AlarmReceiver.class), 0)); ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? mAlarmManager.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(); ? ? } ? ? // 存儲(chǔ)數(shù)據(jù)(存到SharedPreferences中) ? ? private void saveAlarmList(){ ? ? ? ? SharedPreferences.Editor editor = getContext().getSharedPreferences(AlarmView.class.getName(),Context.MODE_PRIVATE).edit(); ? ? ? ? // 存儲(chǔ)數(shù)據(jù)(for循環(huán)遍歷Adapter) ? ? ? ? StringBuffer sb = new StringBuffer(); ? ? ? ? //getCount表示這個(gè)adapter里面有多少item,就是有多少鬧鐘 ? ? ? ? for (int i = 0 ; i < mAdapter.getCount(); i++){ ? ? ? ? ? ? sb.append(mAdapter.getItem(i).getTime()).append(","); ? ? ? ? } ? ? ? ? // 所有的值傳進(jìn)去之后 去掉最后的逗 ? ? ? ? if (sb.length() > 1){ ? ? ? ? ? ? String content = sb.toString().substring(0,sb.length()-1); ? ? ? ? ? ? editor.putString(KEY_ALARM_LIST,content); ? ? ? ? ? ? System.out.println(content);// 輸出存儲(chǔ)的鬧鐘數(shù)據(jù) ? ? ? ? }else { ? ? ? ? ? ? editor.putString(KEY_ALARM_LIST,null); ? ? ? ? } ? ? ? ? editor.commit(); ? ? } ? ? // 讀取已存的數(shù)據(jù) ? ? private void readSavedAlarmList(){ ? ? ? ? // 獲取到SharedPreferences(數(shù)據(jù)內(nèi)容) ? ? ? ? SharedPreferences sp = getContext().getSharedPreferences(AlarmView.class.getName(),Context.MODE_PRIVATE); ? ? ? ? String content = sp.getString(KEY_ALARM_LIST,null); ? ? ? ? // 這里需要判斷,不然沒鬧鐘數(shù)據(jù)的時(shí)候會(huì)有空指針異常 ? ? ? ? if (content != null){ ? ? ? ? ? ? //這里取得每一個(gè)鬧鐘的time添加到數(shù)組里 ? ? ? ? ? ? String[] timeStrings = content.split(","); ? ? ? ? ? ? // 遍歷數(shù)組,把數(shù)據(jù)添加到mAdapter ? ? ? ? ? ? for (String string : timeStrings){ ? ? ? ? ? ? ? ? mAdapter.add(new AlarmData(Long.parseLong(string))); ? ? ? ? ? ? } ? ? ? ? } ? ? } ? ? //鬧鐘的數(shù)據(jù),用一個(gè)類要保存,這是常用的做法 ? ? private static class AlarmData{ ? ? ? ? private long time = 0; ? ? ? ? private String timeLabel = ""; // 在外界獲取時(shí)間的標(biāo)簽的字符串 ? ? ? ? private Calendar date; ? ? ? ? // 鬧鐘響起的時(shí)間 ? ? ? ? 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 AlarmData(String ad){ ? ? ? ? ? ? this.timeLabel = ad; ? ? ? ? } ? ? ? ? public void setTime(long time){ ? ? ? ? ? ? this.time = time; ? ? ? ? } ? ? ? ? public long getTime(){ ? ? ? ? ? ? return time; ? ? ? ? } ? ? ? ? public void setTimeLable(String timeLable){ ? ? ? ? ? ? this.timeLabel = timeLable; ? ? ? ? } ? ? ? ? @Override ? ? ? ? public String toString() { ? ? ? ? ? ? return getTimeLabel(); ? ? ? ? } ? ? ? ? public String getTimeLabel() { ? ? ? ? ? ? return timeLabel; ? ? ? ? } ? ? ? ? //為了給每一個(gè)鬧鐘設(shè)定一個(gè)標(biāo)識(shí),方便取消鬧鐘的使用能知道是哪一個(gè)鬧鐘 ? ? ? ? public int getId(){ ? ? ? ? ? ? return (int) (getTime()/1000/60); ? ? ? ? } ? ? } }
當(dāng)觸發(fā)事件發(fā)生時(shí),我們就要播放我們之前準(zhǔn)備的音樂了,但是怎么播放呢,這里我們就要用到mediaPlayer媒體播放器這個(gè)函數(shù)了,這個(gè)函數(shù)主要就是用來播放音樂或者動(dòng)畫等。當(dāng)開始播放時(shí),我們也需要彈出警告框,提醒用戶去關(guān)閉鬧鐘,所以這里我們需要另外編寫一個(gè)類,用來執(zhí)行這些功能。
PlayAlarmAty類中有播放音樂,開啟震動(dòng),彈出關(guān)閉鬧鐘的dialog。
public class PlayAlarmAty extends Activity { ? ? // 音樂播放器 ? ? private MediaPlayer mMediaPlayer; ? ? private Vibrator vibrator; ? ? private PowerManager.WakeLock mWakelock; ? ? @Override ? ? protected void onCreate(@Nullable Bundle savedInstanceState) { ? ? ? ? super.onCreate(savedInstanceState); ? ? ? ? requestWindowFeature(Window.FEATURE_NO_TITLE); // hide title ? ? ? ? Window win = getWindow(); ? ? ? ? WindowManager.LayoutParams winParams = win.getAttributes(); ? ? ? ? winParams.flags |= (WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD ? ? ? ? ? ? ? ? | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED ? ? ? ? ? ? ? ? | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); ? ? ? ? // 播放鬧鐘鈴聲 ? ? ? ? mMediaPlayer = MediaPlayer.create(this,R.raw.music); //使用create方式,創(chuàng)建MediaPlayer對象 ? ? ? ? mMediaPlayer.setLooping(true); // 設(shè)置是否對播放的音樂進(jìn)行循環(huán)播放 ? ? ? ? mMediaPlayer.start(); ? ? ? ? startVibrator(); ? ? ? ? createDialog(); ? ? } ? ? @Override ? ? protected void onPause() { ? ? ? ? super.onPause(); ? ? ? ? finish(); ? ? ? ? // 釋放鎖屏 ? ? ? ? releaseWakeLock(); ? ? } ? ? @Override ? ? protected void onResume() { ? ? ? ? super.onResume(); ? ? ? ? // 喚醒屏幕 ? ? ? ? acquireWakeLock(); ? ? } ? ? @Override ? ? protected void onDestroy() { ? ? ? ? super.onDestroy(); ? ? ? ? mMediaPlayer.stop(); ? ? ? ? mMediaPlayer.release(); // 釋放掉 ? ? } ? ? // 喚醒屏幕 ? ? private void acquireWakeLock() { ? ? ? ? if (mWakelock == null) { ? ? ? ? ? ? PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); ? ? ? ? ? ? mWakelock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP ? ? ? ? ? ? ? ? ? ? | PowerManager.SCREEN_DIM_WAKE_LOCK, this.getClass() ? ? ? ? ? ? ? ? ? ? .getCanonicalName()); ? ? ? ? ? ? mWakelock.acquire(); ? ? ? ? } ? ? } ? ? // 釋放鎖屏 ? ? private void releaseWakeLock() { ? ? ? ? if (mWakelock != null && mWakelock.isHeld()) { ? ? ? ? ? ? mWakelock.release(); ? ? ? ? ? ? mWakelock = null; ? ? ? ? } ? ? } ? ? // 震動(dòng) ? ? private void startVibrator() { ? ? ? ? // 想設(shè)置震動(dòng)大小可以通過改變pattern來設(shè)定,如果開啟時(shí)間太短,震動(dòng)效果可能感覺不到 ? ? ? ? vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); ? ? ? ? long[] pattern = { 500, 1000, 500, 1000 }; // 停止 開啟 停止 開啟 ? ? ? ? vibrator.vibrate(pattern, 0); ? ? } ? ? private void createDialog() { ? ? ? ? new AlertDialog.Builder(this) ? ? ? ? ? ? ? ? .setIcon(R.drawable.ic_clock) ? ? ? ? ? ? ? ? .setTitle("鬧鐘") ? ? ? ? ? ? ? ? .setMessage("鬧鐘時(shí)間到了!!!") ? ? ? ? ? ? ? ? .setPositiveButton("推遲10分鐘", new DialogInterface.OnClickListener() { ? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int whichButton) { ? ? ? ? ? ? ? ? ? ? ? ? tenMRemind(); ? ? ? ? ? ? ? ? ? ? ? ? mMediaPlayer.stop(); ? ? ? ? ? ? ? ? ? ? ? ? vibrator.cancel(); ? ? ? ? ? ? ? ? ? ? ? ? finish(); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? }) ? ? ? ? ? ? ? ? .setNegativeButton("關(guān)閉", new DialogInterface.OnClickListener() { ? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int whichButton) { ? ? ? ? ? ? ? ? ? ? ? ? mMediaPlayer.stop(); ? ? ? ? ? ? ? ? ? ? ? ? vibrator.cancel(); ? ? ? ? ? ? ? ? ? ? ? ? finish(); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? }).create().show(); ? ? } ? ? // 推遲10分鐘提醒 ? ? private void tenMRemind(){ ? ? ? ? //設(shè)置時(shí)間 ? ? ? ? Calendar calendar_now = Calendar.getInstance(); ? ? ? ? calendar_now.setTimeInMillis(System.currentTimeMillis()); ? ? ? ? calendar_now.set(Calendar.HOUR_OF_DAY, calendar_now.get(Calendar.HOUR_OF_DAY)); ? ? ? ? calendar_now.set(Calendar.MINUTE, calendar_now.get(Calendar.MINUTE)+10); ? ? ? ? calendar_now.set(Calendar.SECOND, 0); ? ? ? ? calendar_now.set(Calendar.MILLISECOND, 0); ? ? ? ? //時(shí)間選擇好了 ? ? ? ? Intent intent = new Intent(this, AlarmReceiver.class); ? ? ? ? //注冊鬧鐘廣播 ? ? ? ? PendingIntent sender = PendingIntent.getBroadcast( ? ? ? ? ? ? ? ? this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); ? ? ? ? AlarmManager am; ? ? ? ? am = (AlarmManager) this.getSystemService(this.ALARM_SERVICE); ? ? ? ? am.set(AlarmManager.RTC_WAKEUP, calendar_now.getTimeInMillis(), sender); ? ? } }
但是要當(dāng)時(shí)間到了啟動(dòng)這個(gè)活動(dòng),就需要一個(gè)接收器,接受這個(gè)事件,所以有需要另一個(gè)類AlarmReceiver。
public class AlarmReceiver extends BroadcastReceiver { ? ? @Override ? ? public void onReceive(Context context, Intent intent) { ? ? ? ? System.out.println("鬧鐘執(zhí)行了"); ? ? ? ? // 鬧鐘執(zhí)行一次就取消當(dāng)前所執(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); // 要啟動(dòng)的類 ? ? ? ? i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 設(shè)置啟動(dòng)的模式 ? ? ? ? context.startActivity(i); ? ? } }
三、秒表功能
秒表功能包含四個(gè)功能鍵,分別為開始,暫停、繼續(xù)和重置。所以需要四個(gè)Button,然后需要三個(gè)EditText分別用來給用戶輸入時(shí)分秒。具體的xml代碼如下:
// 秒表 <com.example.tsclock.StopWatchView ? ? ? android:id="@+id/tabStopWatch" ? ? ? android:layout_width="match_parent" ? ? ? android:layout_height="match_parent" ? ? ? android:orientation="vertical"> <LinearLayout ? ? ? ?android:layout_width="match_parent" ? ? ? ?android:layout_height="wrap_content" ? ? ? ?android:orientation="horizontal"> <TextView ? ? ? ?android:id="@+id/timeHour" ? ? ? ?android:layout_width="0dp" ? ? ? ?android:layout_height="wrap_content" ? ? ? ?android:layout_weight="1" ? ? ? ?android:textAppearance="?android:attr/textAppearanceLarge"/> <TextView ? ? ? ?android:layout_width="wrap_content" ? ? ? ?android:layout_height="wrap_content" ? ? ? ?android:text=":" ? ? ? ?android:textAppearance="?android:attr/textAppearanceLarge"/> <TextView ? ? ? ?android:id="@+id/timeMin" ? ? ? ?android:layout_width="0dp" ? ? ? ?android:layout_height="wrap_content" ? ? ? ?android:layout_weight="1" ? ? ? ?android:textAppearance="?android:attr/textAppearanceLarge"/> <TextView ? ? ? ?android:layout_width="wrap_content" ? ? ? ?android:layout_height="wrap_content" ? ? ? ?android:text=":" ? ? ? ?android:textAppearance="?android:attr/textAppearanceLarge"/> <TextView ? ? ? ?android:id="@+id/timeSec" ? ? ? ?android:layout_width="0dp" ? ? ? ?android:layout_height="wrap_content" ? ? ? ?android:layout_weight="1" ? ? ? ?android:textAppearance="?android:attr/textAppearanceLarge"/> <TextView ? ? ? android:layout_width="wrap_content" ? ? ? android:layout_height="wrap_content" ? ? ? android:text="." ? ? ? android:textAppearance="?android:attr/textAppearanceLarge"/> <TextView ? ? ? ?android:id="@+id/timeMSec" ? ? ? ?android:layout_width="0dp" ? ? ? ?android:layout_height="wrap_content" ? ? ? ?android:layout_weight="1" ? ? ? ?android:textAppearance="?android:attr/textAppearanceLarge"/> ?</LinearLayout> <ListView ? ? ? ?android:id="@+id/lvWatchTime" ? ? ? ?android:layout_width="match_parent" ? ? ? ?android:layout_height="0dp" ? ? ? ?android:layout_weight="1"/> <LinearLayout ? ? ? ?android:layout_width="match_parent" ? ? ? ?android:layout_height="wrap_content" ? ? ? ?android:orientation="horizontal"> <Button ? ? ? ? android:id="@+id/btnSWStart" ? ? ? ? android:layout_width="0dp" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:layout_weight="1" ? ? ? ? android:text="@string/start" ? ? ? ? android:textColor="#FFFFFF" ? ? ? ? android:background="@color/colorBlue"/> <Button ? ? ? ? android:id="@+id/btnSWPause" ? ? ? ? android:layout_width="0dp" ? ? ? ? android:layout_weight="1" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:text="@string/pause" ? ? ? ? android:textColor="#FFFFFF" ? ? ? ? android:background="@color/colorBlue"/> <Button ? ? ? ? ?android:id="@+id/btnSWResume" ? ? ? ? ?android:layout_width="0dp" ? ? ? ? ?android:layout_height="wrap_content" ? ? ? ? ?android:layout_weight="1" ? ? ? ? ?android:text="@string/resume" ? ? ? ? ?android:textColor="#FFFFFF" ? ? ? ? ?android:background="@color/colorBlue"/> <Button ? ? ? ? ?android:id="@+id/btnSWLap" ? ? ? ? ?android:layout_width="0dp" ? ? ? ? ?android:layout_height="wrap_content" ? ? ? ? ?android:layout_weight="1" ? ? ? ? ?android:text="@string/lap" ? ? ? ? android:textColor="#FFFFFF" ? ? ? ? android:background="@color/colorBlue"/> <Button ? ? ? ? ? android:id="@+id/btnSWReset" ? ? ? ? ? android:layout_width="0dp" ? ? ? ? ? android:layout_height="wrap_content" ? ? ? ? ? android:layout_weight="1" ? ? ? ? ? android:text="@string/reset" ? ? ? ? ? android:textColor="#FFFFFF" ? ? ? ? ?android:background="@color/colorBlue"/> ? ? </LinearLayout> </com.example.tsclock.StopWatchView>
在秒表功能中,含有四個(gè)Button,但是有時(shí)候只要顯示一個(gè)或者是兩個(gè)其余的就需要隱藏,所以這里就需要用到Button中的屬性setVisibility(View.GONE)或者是setVisibility(View.VISIBLE),這是用來隱藏和顯示Button。
有時(shí)候我們需要考慮系統(tǒng)的健壯性,比如當(dāng)我們輸入大于59的數(shù)或者是小于0的數(shù),這時(shí)候我們需要系統(tǒng)檢測出來,并進(jìn)行修正。
需要注意的就是,當(dāng)我們修改計(jì)時(shí)的時(shí)間的時(shí)候,當(dāng)我們不小心將數(shù)目清空的時(shí)候,這時(shí)候就會(huì)將空指針上傳,導(dǎo)致系統(tǒng)的崩潰,所以我們需要判斷是不是空指針,防止越界報(bào)錯(cuò)。
該秒表功能有五個(gè)Button,所以需要對每個(gè)Button添加觸發(fā)事件,其實(shí)startTime()函數(shù)的功能為開始計(jì)時(shí),stopTime()函數(shù)的功能為暫停計(jì)時(shí)。所以這里需要弄清楚的就是什么時(shí)候該讓那些按鈕隱藏,什么時(shí)候該讓那些按鈕顯示。
public class StopWatchView extends LinearLayout { ? ? private TextView tvHour,tvMin,tvSec,tvMSec; ? ? private Button btnSWStart,btnSWResume,btnSWReset,btnSWLap,btnSWPause; ? ? private ListView lvTimeList; ? ? private ArrayAdapter<String> adapter; ? ? private Timer mTimer = new Timer(); ? ? private TimerTask mTimerTask = null; ? ? private int tenMSec = 0; ? ? private TimerTask showTimerTask = null; ? ? private static final int MSG_WHAT_SHOW_TIME = 1; ? ? public StopWatchView(Context context, @Nullable 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"); ? ? ? ? // 計(jì)時(shí) ? ? ? ? btnSWLap = (Button) findViewById(R.id.btnSWLap); ? ? ? ? btnSWLap.setOnClickListener(new OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 時(shí) ? ? ? ? 分 ? ? ? ? ? ? ? 秒 ? ? ? ? ? ?毫秒 ? ? ? ? ? ? ? ? adapter.insert(String.format("%d:%d:%d.%d",tenMSec/100/60/60,tenMSec/100/60%60,tenMSec/100%60,tenMSec%100),0); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? // 開始 ? ? ? ? btnSWStart = (Button) findViewById(R.id.btnSWStart); ? ? ? ? btnSWStart.setOnClickListener(new OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? startTimer(); ? ? ? ? ? ? ? ? btnSWStart.setVisibility(View.GONE); ? ? ? ? ? ? ? ? btnSWPause.setVisibility(View.VISIBLE); ? ? ? ? ? ? ? ? btnSWLap.setVisibility(View.VISIBLE); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? // 暫停 ? ? ? ? btnSWPause = (Button) findViewById(R.id.btnSWPause); ? ? ? ? btnSWPause.setOnClickListener(new OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? stopTimer(); ? ? ? ? ? ? ? ? btnSWPause.setVisibility(View.GONE); ? ? ? ? ? ? ? ? btnSWResume.setVisibility(View.VISIBLE); ? ? ? ? ? ? ? ? btnSWLap.setVisibility(View.GONE); ? ? ? ? ? ? ? ? btnSWReset.setVisibility(View.VISIBLE); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? // 繼續(xù) ? ? ? ? btnSWResume = (Button) findViewById(R.id.btnSWResume); ? ? ? ? btnSWResume.setOnClickListener(new OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? startTimer(); ? ? ? ? ? ? ? ? btnSWResume.setVisibility(View.GONE); ? ? ? ? ? ? ? ? btnSWPause.setVisibility(View.VISIBLE); ? ? ? ? ? ? ? ? btnSWReset.setVisibility(View.GONE); ? ? ? ? ? ? ? ? btnSWLap.setVisibility(View.VISIBLE); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? // 重置 ? ? ? ? btnSWReset = (Button) findViewById(R.id.btnSWReset); ? ? ? ? btnSWReset.setOnClickListener(new OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? stopTimer(); ? ? ? ? ? ? ? ? tenMSec = 0; ? ? ? ? ? ? ? ? adapter.clear();// 重置需要清除列表 ? ? ? ? ? ? ? ? btnSWLap.setVisibility(View.GONE); ? ? ? ? ? ? ? ? btnSWPause.setVisibility(View.GONE); ? ? ? ? ? ? ? ? btnSWResume.setVisibility(View.GONE); ? ? ? ? ? ? ? ? btnSWReset.setVisibility(View.GONE); ? ? ? ? ? ? ? ? btnSWStart.setVisibility(View.VISIBLE); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? // 設(shè)置除了開始之外 其它四個(gè)按鈕不可見 ? ? ? ? btnSWLap.setVisibility(View.GONE); ? ? ? ? btnSWPause.setVisibility(View.GONE); ? ? ? ? btnSWResume.setVisibility(View.GONE); ? ? ? ? btnSWReset.setVisibility(View.GONE); ? ? ? ? lvTimeList = (ListView) findViewById(R.id.lvWatchTime); ? ? ? ? // 初始化話adapter ? ? ? ? adapter = new ArrayAdapter<String>(getContext(),android.R.layout.simple_list_item_1); ? ? ? ? lvTimeList.setAdapter(adapter); ? ? ? ? // 使用showTimerTask不斷執(zhí)行刷新的操作 ? ? ? ? showTimerTask = new TimerTask() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? handler.sendEmptyMessage(MSG_WHAT_SHOW_TIME); ? ? ? ? ? ? } ? ? ? ? }; ? ? ? ? mTimer.schedule(showTimerTask,200,200); // 一秒鐘刷新五次 ? ? } ? ? private void startTimer(){ ? ? ? ? if (mTimerTask == null){ ? ? ? ? ? ? mTimerTask = new TimerTask() {// 計(jì)時(shí)的timerTask ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? ? ? tenMSec++; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? }; ? ? ? ? ? ? mTimer.schedule(mTimerTask,10,10); // 每隔十毫秒執(zhí)行一次 ? ? ? ? } ? ? } ? ? private void stopTimer(){ ? ? ? ? if (mTimerTask != null){ ? ? ? ? ? ? mTimerTask.cancel(); ? ? ? ? ? ? mTimerTask = null; ? ? ? ? } ? ? } ? ? // 呈現(xiàn)時(shí)間的handler ? ? private Handler handler = new Handler(){ ? ? ? ? @Override ? ? ? ? public void handleMessage(@NonNull Message msg) { ? ? ? ? ? ? super.handleMessage(msg); ? ? ? ? ? ? switch (msg.what){ ? ? ? ? ? ? ? ? case MSG_WHAT_SHOW_TIME: ? ? ? ? ? ? ? ? ? ? tvHour.setText(tenMSec/100/60/60+""); // 時(shí) ? ? ? ? ? ? ? ? ? ? tvMin.setText(tenMSec/100/60%60+""); // 分 ? ? ? ? ? ? ? ? ? ? tvSec.setText(tenMSec/100%60+""); // 秒 ? ? ? ? ? ? ? ? ? ? tvMSec.setText(tenMSec%100+""); // 毫秒 ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? default: ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? } ? ? }; ? ? public void onDestory() { ? ? ? ? mTimer.cancel(); ? ? } }
四、計(jì)時(shí)器功能
這個(gè)和上面講了秒表比較類似,不同的是多一個(gè)Button按鈕用來計(jì)時(shí),還多一個(gè)EditView(毫秒值),另外還需要一個(gè)ListView用來顯示計(jì)時(shí)的時(shí)間,詳細(xì)的xml代碼如下:
// 計(jì)時(shí)器 <com.example.tsclock.TimerView ? ? ? ? android:id="@+id/tabTimer" ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="match_parent" ? ? ? ? android:orientation="vertical"> <LinearLayout ? ? ? ? android:orientation="horizontal" ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="0dp" ? ? ? ? android:layout_weight="1"> <EditText ? ? ? ? android:id="@+id/etHour" ? ? ? ? android:layout_width="0dp" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:layout_weight="1" ? ? ? ? android:inputType="number" ? ? ? ? android:singleLine="true" ? ? ? ? android:textAppearance="?android:attr/textAppearanceLarge"/> <TextView ? ? ? ? android:layout_width="wrap_content" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:text=":" ? ? ? ? android:textAppearance="?android:attr/textAppearanceLarge"/> <EditText ? ? ? ? android:id="@+id/etMin" ? ? ? ? android:layout_width="0dp" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:layout_weight="1" ? ? ? ? android:inputType="number" ? ? ? ? android:singleLine="true" ? ? ? ? android:textAppearance="?android:attr/textAppearanceLarge"/> <TextView ? ? ? ? android:layout_width="wrap_content" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:text=":" ? ? ? ? android:textAppearance="?android:attr/textAppearanceLarge"/> <EditText ? ? ? ? android:id="@+id/etSec" ? ? ? ? android:layout_width="0dp" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:layout_weight="1" ? ? ? ? android:inputType="number" ? ? ? ? android:singleLine="true" ? ? ? ? android:textAppearance="?android:attr/textAppearanceLarge"/> </LinearLayout> <LinearLayout ? ? ? ? android:id="@+id/btnGroup" ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:orientation="horizontal"> <Button ? ? ? ? android:id="@+id/btnStart" ? ? ? ? android:layout_width="0dp" ? ? ? ? android:text="@string/start" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:layout_weight="1" ? ? ? ? android:textColor="#FFFFFF" ? ? ? ? android:background="@color/colorBlue"/> <Button ? ? ? ? android:id="@+id/btnPause" ? ? ? ? android:layout_width="0dp" ? ? ? ? android:text="@string/pause" ? ? ? ? android:layout_height="wrap_content" ? ? ? ? android:layout_weight="1" ? ? ? ? android:textColor="#FFFFFF" ? ? ? ? android:background="@color/colorBlue"/> <Button ? ? ? ? ?android:id="@+id/btnResume" ? ? ? ? ?android:layout_width="0dp" ? ? ? ? ?android:text="@string/resume" ? ? ? ? ?android:layout_height="wrap_content" ? ? ? ? ?android:layout_weight="1" ? ? ? ? ?android:textColor="#FFFFFF" ? ? ? ? ?android:background="@color/colorBlue"/> <Button ? ? ? ? ?android:id="@+id/btnReset" ? ? ? ? ?android:layout_width="0dp" ? ? ? ? ?android:text="@string/reset" ? ? ? ? ?android:layout_height="wrap_content" ? ? ? ? ?android:layout_weight="1" ? ? ? ? ?android:textColor="#FFFFFF" ? ? ? ? ?android:background="@color/colorBlue"/> ? ?</LinearLayout> </com.example.tsclock.TimerView>
計(jì)時(shí)器功能和秒表功能差不多
public class TimerView extends LinearLayout { ? ? private Button btnStart,btnPause,btnResume,btnReset; ? ? private EditText etHour,etMin,etSec; ? ? private Timer mTimer = new Timer(); // 計(jì)時(shí)器 ? ? private TimerTask mTimerTask = null; ? ? private int allTimerCount = 0; ? ? private static final int MSG_WHAT_TIME_IS_UP = 1; ? ? private static final int MSG_WHAT_TIME_IS_TICK = 2; // 時(shí)鐘一格一格的往下走 ? ? private ListView mListView; ? ? public TimerView(Context context) { ? ? ? ? super(context); ? ? } ? ? public TimerView(Context context, @Nullable AttributeSet attrs) { ? ? ? ? super(context, attrs); ? ? } ? ? @Override ? ? protected void onFinishInflate() { ? ? ? ? super.onFinishInflate(); ? ? ? ? //開始 ? ? ? ? btnStart = (Button) findViewById(R.id.btnStart); ? ? ? ? btnStart.setOnClickListener(new OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? startTimer(); ? ? ? ? ? ? ? ? btnStart.setVisibility(View.GONE); ? ? ? ? ? ? ? ? btnPause.setVisibility(View.VISIBLE); ? ? ? ? ? ? ? ? btnReset.setVisibility(View.VISIBLE); ? ? ? ? ? ? ? ? etHour.setEnabled(false); ? ? ? ? ? ? ? ? etMin.setEnabled(false); ? ? ? ? ? ? ? ? etSec.setEnabled(false); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? // 暫停 ? ? ? ? btnPause = (Button) findViewById(R.id.btnPause); ? ? ? ? btnPause.setOnClickListener(new OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? stopTimer(); ? ? ? ? ? ? ? ? btnPause.setVisibility(View.GONE); ? ? ? ? ? ? ? ? btnResume.setVisibility(View.VISIBLE); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? // 繼續(xù) ? ? ? ? btnResume = (Button) findViewById(R.id.btnResume); ? ? ? ? btnResume.setOnClickListener(new OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? startTimer(); ? ? ? ? ? ? ? ? btnResume.setVisibility(View.GONE); ? ? ? ? ? ? ? ? btnPause.setVisibility(View.VISIBLE); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? // 重置 ? ? ? ? btnReset = (Button) findViewById(R.id.btnReset); ? ? ? ? btnReset.setOnClickListener(new OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? stopTimer(); ? ? ? ? ? ? ? ? etHour.setText("00"); ? ? ? ? ? ? ? ? etMin.setText("00"); ? ? ? ? ? ? ? ? etSec.setText("00"); ? ? ? ? ? ? ? ? etHour.setEnabled(true); ? ? ? ? ? ? ? ? etMin.setEnabled(true); ? ? ? ? ? ? ? ? etSec.setEnabled(true); ? ? ? ? ? ? ? ? btnStart.setVisibility(View.VISIBLE); ? ? ? ? ? ? ? ? btnPause.setVisibility(View.GONE); ? ? ? ? ? ? ? ? btnResume.setVisibility(View.GONE); ? ? ? ? ? ? ? ? btnReset.setVisibility(View.GONE); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? etHour = (EditText) findViewById(R.id.etHour); ? ? ? ? etMin = (EditText) findViewById(R.id.etMin); ? ? ? ? etSec = (EditText) findViewById(R.id.etSec); ? ? ? ? etHour.setText("00"); ? ? ? ? // 添加事件監(jiān)聽器 ? ? ? ? etHour.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){ ? ? ? ? ? ? ? ? ? ? ? ? etHour.setText("59"); ? ? ? ? ? ? ? ? ? ? }else if (value < 0){ ? ? ? ? ? ? ? ? ? ? ? ? etHour.setText("0"); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? 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("0"); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? 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)){ // 當(dāng)文字框中不為空 ? ? ? ? ? ? ? ? ? ? int value = Integer.parseInt(s.toString()); ? ? ? ? ? ? ? ? ? ? if (value > 59){ ? ? ? ? ? ? ? ? ? ? ? ? etSec.setText("59"); ? ? ? ? ? ? ? ? ? ? }else if (value < 0){ ? ? ? ? ? ? ? ? ? ? ? ? etSec.setText("0"); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? checkToEnableBtnStart(); ? ? ? ? ? ? } ? ? ? ? ? ? @Override ? ? ? ? ? ? public void beforeTextChanged(CharSequence s, int start, int count, int after) { ? ? ? ? ? ? } ? ? ? ? ? ? @Override ? ? ? ? ? ? public void afterTextChanged(Editable s) { ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? btnStart.setVisibility(View.VISIBLE); // 設(shè)置開始可見 ? ? ? ? btnStart.setEnabled(false); // 不可點(diǎn)擊(開始還沒有設(shè)置時(shí)間) ? ? ? ? btnPause.setVisibility(View.GONE); // 設(shè)置暫停不可見 ? ? ? ? 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 (mTimerTask == null){ ? ? ? ? ? ? // 所使用時(shí)間的計(jì)數(shù) ? ? ? ? ? ? allTimerCount = Integer.parseInt(etHour.getText().toString())*60*60+Integer.parseInt(etMin.getText().toString())*60+Integer.parseInt(etSec.getText().toString()); ? ? ? ? ? ? mTimerTask = new TimerTask() { ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? public void run() { // run方法會(huì)被mTimer執(zhí)行 ? ? ? ? ? ? ? ? ? ? // 每執(zhí)行一次 計(jì)數(shù)減一 ? ? ? ? ? ? ? ? ? ? allTimerCount--; ? ? ? ? ? ? ? ? ? ? // 獲取到當(dāng) ? ? ? ? ? ? ? ? ? ? mHandler.sendEmptyMessage(MSG_WHAT_TIME_IS_TICK); ? ? ? ? ? ? ? ? ? ? if (allTimerCount <= 0){ ? ? ? ? ? ? ? ? ? ? ? ? // 訪問mHandler ? ? ? ? ? ? ? ? ? ? ? ? mHandler.sendEmptyMessage(MSG_WHAT_TIME_IS_UP); ? ? ? ? ? ? ? ? ? ? ? ? stopTimer(); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? }; ? ? ? ? ? ? mTimer.schedule(mTimerTask,1000,1000); // run方法每隔一秒執(zhí)行一次 ? ? ? ? } ? ? } ? ? private void stopTimer(){ ? ? ? ? if (mTimerTask != null){ ? ? ? ? ? ? mTimerTask.cancel(); ? ? ? ? ? ? mTimerTask = null; ? ? ? ? } ? ? } ? ? private Handler mHandler = new Handler(){ ? ? ? ? @Override ? ? ? ? public void handleMessage(@NonNull Message msg) { ? ? ? ? ? ? super.handleMessage(msg); ? ? ? ? ? ? switch (msg.what){ ? ? ? ? ? ? ? ? case MSG_WHAT_TIME_IS_TICK: ? ? ? ? ? ? ? ? ? ? int hour = allTimerCount/60/60; ? ? ? ? ? ? ? ? ? ? int min = (allTimerCount/60)%60; ? ? ? ? ? ? ? ? ? ? int sec = allTimerCount%60; ? ? ? ? ? ? ? ? ? ? etHour.setText(hour+""); ? ? ? ? ? ? ? ? ? ? etMin.setText(min+""); ? ? ? ? ? ? ? ? ? ? etSec.setText(sec+""); ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? case MSG_WHAT_TIME_IS_UP: ? ? ? ? ? ? ? ? ? ? // 執(zhí)行彈出對話框操作 ? ? ? ? ? ? ? ? ? ? // 把時(shí)間停止(彈出一個(gè)對話框) ? ? ? ? ? ? ? ? ? ? new AlertDialog.Builder(getContext()).setTitle("時(shí)間到了??!!").setNegativeButton("退出",null).show(); ? ? ? ? ? ? ? ? ? ? btnPause.setVisibility(View.GONE); ? ? ? ? ? ? ? ? ? ? btnResume.setVisibility(View.GONE); ? ? ? ? ? ? ? ? ? ? btnReset.setVisibility(View.GONE); ? ? ? ? ? ? ? ? ? ? btnStart.setVisibility(View.VISIBLE); ? ? ? ? ? ? ? ? ? ? etHour.setEnabled(true); ? ? ? ? ? ? ? ? ? ? etMin.setEnabled(true); ? ? ? ? ? ? ? ? ? ? etSec.setEnabled(true); ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? default: ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? } ? ? }; }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 簡單實(shí)現(xiàn)Android鬧鐘程序 附源碼
- Android編程實(shí)現(xiàn)鬧鐘的方法詳解
- Android實(shí)現(xiàn)簡易鬧鐘功能
- 簡單實(shí)現(xiàn)Android鬧鐘功能
- Android鬧鐘設(shè)置的解決方案
- Android鬧鐘機(jī)制實(shí)現(xiàn)定時(shí)任務(wù)功能
- Android通過AlarmManager類實(shí)現(xiàn)簡單鬧鐘功能
- Android鬧鐘啟動(dòng)時(shí)間設(shè)置無效問題的解決方法
- Android手機(jī)鬧鐘用法實(shí)例
- Android編程鬧鐘設(shè)置方法詳解
相關(guān)文章
Flutter實(shí)現(xiàn)倒計(jì)時(shí)功能
這篇文章主要為大家詳細(xì)介紹了Flutter實(shí)現(xiàn)倒計(jì)時(shí)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03Android進(jìn)階KOOM線上APM監(jiān)控全面剖析
這篇文章主要為大家介紹了Android進(jìn)階KOOM線上APM監(jiān)控全面剖析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01Android實(shí)現(xiàn)apk插件方式換膚的實(shí)例講解
在本篇文章里小編給大家整理的是關(guān)于Android實(shí)現(xiàn)apk插件方式換膚的實(shí)例代碼以及相關(guān)知識(shí)點(diǎn),有需要的朋友們學(xué)習(xí)下。2019-10-10Android Notification使用方法總結(jié)
這篇文章主要介紹了Android Notification使用方法總結(jié)的相關(guān)資料,這里提供了四種使用方法,需要的朋友可以參考下2017-09-09如何利用Flutter實(shí)現(xiàn)酷狗流暢Tabbar效果
這篇文章主要給大家介紹了關(guān)于如何利用Flutter實(shí)現(xiàn)酷狗流暢Tabbar效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-02-02Android實(shí)現(xiàn)ImageView陰影和圖層效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)ImageView陰影和圖層效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02Android開發(fā)基礎(chǔ)實(shí)現(xiàn)音頻文件的播放詳解
這篇文章主要為大家介紹了Android開發(fā)基礎(chǔ)實(shí)現(xiàn)音頻文件的播放詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02