Android開發(fā)實戰(zhàn)鬧鐘項目
本文實例為大家分享了Android實戰(zhàn)鬧鐘項目的具體代碼,供大家參考,具體內(nèi)容如下
一、鬧鐘功能的介紹以及界面的展示
該鬧鐘是根據(jù)我們手機鬧鐘設計的一個簡單的鬧鐘APP,其中包含時鐘、鬧鐘、秒表和計時器功能。用戶可以對鬧鐘添加和刪除,可以對秒表計時、暫停和重置,對計時器可以暫停、計時、繼續(xù)和重置等功能。
二、介紹系統(tǒng)的設計界面
鬧鐘的布局文件代碼如下
由于該鬧鐘系統(tǒng)包含時鐘、鬧鐘、計時器、秒表四個功能,所以只要在xml文件插入TabHost控件就能實現(xiàn)在手機上更加簡潔地展示四個功能。后面只需要在TabHost中插入四個Tab用來切換展示的界面,具體的代碼實現(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("時鐘").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獲取當前系統(tǒng)的時間,最后再每過1秒鐘刷新一次,這樣就能夠再TextView中出現(xiàn)時間在不停的變化。
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每秒執(zhí)行一次 ? ? ? ? timerHandler.sendEmptyMessage(0); ? ? } ? ? // 可見屬性發(fā)生變化之后 ? ? @Override ? ? protected void onVisibilityChanged(@NonNull View changedView, int visibility) { ? ? ? ? super.onVisibilityChanged(changedView, visibility); ? ? ? ? if (visibility == View.VISIBLE){ // 如果可見 則發(fā)送一個消息 ? ? ? ? ? ? timerHandler.sendEmptyMessage(0); ? ? ? ? }else{ ? ? ? ? ? ? ? ? ? ? ? ? ? // ?如果不可見 移除所有的消息 ? ? ? ? ? ? timerHandler.removeMessages(0); ? ? ? ? } ? ? } ? ? // 重新刷新時間 ? ? private void refreshTime(){ ? ? ? ? // 呈現(xiàn)一個時間對象 ? ? ? ? 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){ ? ? ? ? ? ? // 呈現(xiàn)出來 ? ? ? ? ? ? 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
需要判斷時間到了需要觸發(fā)事件,需要播放音樂和震動。所以播放音樂和震動放在另一個活動中(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)的鬧鐘服務 ? ? 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); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 系統(tǒng)的簡單資源 ? ? ? ? mAdapter = new ArrayAdapter<AlarmView.AlarmData>(getContext(),android.R.layout.simple_list_item_1); ? ? ? ? // 設置Adapter ? ? ? ? lvAlarmList.setAdapter(mAdapter); ? ? ? ? // 讀取已經(jīng)存儲在SharedPreferences中的數(shù)據(jù) ? ? ? ? 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.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 (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, // 時間誤差范圍 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(); ? ? } ? ? // 存儲數(shù)據(jù)(存到SharedPreferences中) ? ? private void saveAlarmList(){ ? ? ? ? SharedPreferences.Editor editor = getContext().getSharedPreferences(AlarmView.class.getName(),Context.MODE_PRIVATE).edit(); ? ? ? ? // 存儲數(shù)據(jù)(for循環(huán)遍歷Adapter) ? ? ? ? StringBuffer sb = new StringBuffer(); ? ? ? ? //getCount表示這個adapter里面有多少item,就是有多少鬧鐘 ? ? ? ? for (int i = 0 ; i < mAdapter.getCount(); i++){ ? ? ? ? ? ? sb.append(mAdapter.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);// 輸出存儲的鬧鐘數(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ù)的時候會有空指針異常 ? ? ? ? if (content != null){ ? ? ? ? ? ? //這里取得每一個鬧鐘的time添加到數(shù)組里 ? ? ? ? ? ? String[] timeStrings = content.split(","); ? ? ? ? ? ? // 遍歷數(shù)組,把數(shù)據(jù)添加到mAdapter ? ? ? ? ? ? for (String string : timeStrings){ ? ? ? ? ? ? ? ? mAdapter.add(new AlarmData(Long.parseLong(string))); ? ? ? ? ? ? } ? ? ? ? } ? ? } ? ? //鬧鐘的數(shù)據(jù),用一個類要保存,這是常用的做法 ? ? private static class AlarmData{ ? ? ? ? private long time = 0; ? ? ? ? private String timeLabel = ""; // 在外界獲取時間的標簽的字符串 ? ? ? ? private Calendar date; ? ? ? ? // 鬧鐘響起的時間 ? ? ? ? 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; ? ? ? ? } ? ? ? ? //為了給每一個鬧鐘設定一個標識,方便取消鬧鐘的使用能知道是哪一個鬧鐘 ? ? ? ? public int getId(){ ? ? ? ? ? ? return (int) (getTime()/1000/60); ? ? ? ? } ? ? } }
當觸發(fā)事件發(fā)生時,我們就要播放我們之前準備的音樂了,但是怎么播放呢,這里我們就要用到mediaPlayer媒體播放器這個函數(shù)了,這個函數(shù)主要就是用來播放音樂或者動畫等。當開始播放時,我們也需要彈出警告框,提醒用戶去關閉鬧鐘,所以這里我們需要另外編寫一個類,用來執(zhí)行這些功能。
PlayAlarmAty類中有播放音樂,開啟震動,彈出關閉鬧鐘的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); // 設置是否對播放的音樂進行循環(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; ? ? ? ? } ? ? } ? ? // 震動 ? ? private void startVibrator() { ? ? ? ? // 想設置震動大小可以通過改變pattern來設定,如果開啟時間太短,震動效果可能感覺不到 ? ? ? ? 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("鬧鐘時間到了!!!") ? ? ? ? ? ? ? ? .setPositiveButton("推遲10分鐘", new DialogInterface.OnClickListener() { ? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int whichButton) { ? ? ? ? ? ? ? ? ? ? ? ? tenMRemind(); ? ? ? ? ? ? ? ? ? ? ? ? mMediaPlayer.stop(); ? ? ? ? ? ? ? ? ? ? ? ? vibrator.cancel(); ? ? ? ? ? ? ? ? ? ? ? ? finish(); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? }) ? ? ? ? ? ? ? ? .setNegativeButton("關閉", new DialogInterface.OnClickListener() { ? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int whichButton) { ? ? ? ? ? ? ? ? ? ? ? ? mMediaPlayer.stop(); ? ? ? ? ? ? ? ? ? ? ? ? vibrator.cancel(); ? ? ? ? ? ? ? ? ? ? ? ? finish(); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? }).create().show(); ? ? } ? ? // 推遲10分鐘提醒 ? ? private void tenMRemind(){ ? ? ? ? //設置時間 ? ? ? ? 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); ? ? ? ? //時間選擇好了 ? ? ? ? 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); ? ? } }
但是要當時間到了啟動這個活動,就需要一個接收器,接受這個事件,所以有需要另一個類AlarmReceiver。
public class AlarmReceiver extends BroadcastReceiver { ? ? @Override ? ? public void onReceive(Context context, Intent intent) { ? ? ? ? System.out.println("鬧鐘執(zhí)行了"); ? ? ? ? // 鬧鐘執(zhí)行一次就取消當前所執(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); // 要啟動的類 ? ? ? ? i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 設置啟動的模式 ? ? ? ? context.startActivity(i); ? ? } }
三、秒表功能
秒表功能包含四個功能鍵,分別為開始,暫停、繼續(xù)和重置。所以需要四個Button,然后需要三個EditText分別用來給用戶輸入時分秒。具體的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>
在秒表功能中,含有四個Button,但是有時候只要顯示一個或者是兩個其余的就需要隱藏,所以這里就需要用到Button中的屬性setVisibility(View.GONE)或者是setVisibility(View.VISIBLE),這是用來隱藏和顯示Button。
有時候我們需要考慮系統(tǒng)的健壯性,比如當我們輸入大于59的數(shù)或者是小于0的數(shù),這時候我們需要系統(tǒng)檢測出來,并進行修正。
需要注意的就是,當我們修改計時的時間的時候,當我們不小心將數(shù)目清空的時候,這時候就會將空指針上傳,導致系統(tǒng)的崩潰,所以我們需要判斷是不是空指針,防止越界報錯。
該秒表功能有五個Button,所以需要對每個Button添加觸發(fā)事件,其實startTime()函數(shù)的功能為開始計時,stopTime()函數(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"); ? ? ? ? // 計時 ? ? ? ? btnSWLap = (Button) findViewById(R.id.btnSWLap); ? ? ? ? btnSWLap.setOnClickListener(new OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 時 ? ? ? ? 分 ? ? ? ? ? ? ? 秒 ? ? ? ? ? ?毫秒 ? ? ? ? ? ? ? ? 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); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? // 設置除了開始之外 其它四個按鈕不可見 ? ? ? ? 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() {// 計時的timerTask ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? ? ? tenMSec++; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? }; ? ? ? ? ? ? mTimer.schedule(mTimerTask,10,10); // 每隔十毫秒執(zhí)行一次 ? ? ? ? } ? ? } ? ? private void stopTimer(){ ? ? ? ? if (mTimerTask != null){ ? ? ? ? ? ? mTimerTask.cancel(); ? ? ? ? ? ? mTimerTask = null; ? ? ? ? } ? ? } ? ? // 呈現(xiàn)時間的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+""); // 時 ? ? ? ? ? ? ? ? ? ? tvMin.setText(tenMSec/100/60%60+""); // 分 ? ? ? ? ? ? ? ? ? ? tvSec.setText(tenMSec/100%60+""); // 秒 ? ? ? ? ? ? ? ? ? ? tvMSec.setText(tenMSec%100+""); // 毫秒 ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? default: ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? } ? ? }; ? ? public void onDestory() { ? ? ? ? mTimer.cancel(); ? ? } }
四、計時器功能
這個和上面講了秒表比較類似,不同的是多一個Button按鈕用來計時,還多一個EditView(毫秒值),另外還需要一個ListView用來顯示計時的時間,詳細的xml代碼如下:
// 計時器 <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>
計時器功能和秒表功能差不多
public class TimerView extends LinearLayout { ? ? private Button btnStart,btnPause,btnResume,btnReset; ? ? private EditText etHour,etMin,etSec; ? ? private Timer mTimer = new Timer(); // 計時器 ? ? 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; // 時鐘一格一格的往下走 ? ? 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)){ // 當文字框中不為空 ? ? ? ? ? ? ? ? ? ? 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); // 設置開始可見 ? ? ? ? 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 (mTimerTask == null){ ? ? ? ? ? ? // 所使用時間的計數(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方法會被mTimer執(zhí)行 ? ? ? ? ? ? ? ? ? ? // 每執(zhí)行一次 計數(shù)減一 ? ? ? ? ? ? ? ? ? ? allTimerCount--; ? ? ? ? ? ? ? ? ? ? // 獲取到當 ? ? ? ? ? ? ? ? ? ? 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í)行彈出對話框操作 ? ? ? ? ? ? ? ? ? ? // 把時間停止(彈出一個對話框) ? ? ? ? ? ? ? ? ? ? new AlertDialog.Builder(getContext()).setTitle("時間到了??!!").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)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android進階KOOM線上APM監(jiān)控全面剖析
這篇文章主要為大家介紹了Android進階KOOM線上APM監(jiān)控全面剖析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01如何利用Flutter實現(xiàn)酷狗流暢Tabbar效果
這篇文章主要給大家介紹了關于如何利用Flutter實現(xiàn)酷狗流暢Tabbar效果的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2022-02-02Android實現(xiàn)ImageView陰影和圖層效果
這篇文章主要為大家詳細介紹了Android實現(xiàn)ImageView陰影和圖層效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02Android開發(fā)基礎實現(xiàn)音頻文件的播放詳解
這篇文章主要為大家介紹了Android開發(fā)基礎實現(xiàn)音頻文件的播放詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02