Android开发实战闹钟项目
(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun)
本文实例为大家分享了Android实战闹钟项目的具体代码,供大家参考,具体内容如下
一、闹钟功能的介绍以及界面的展示
该闹钟是根据我们手机闹钟设计的一个简单的闹钟APP,其中包含时钟、闹钟、秒表和计时器功能。用户可以对闹钟添加和删除,可以对秒表计时、暂停和重置,对计时器可以暂停、计时、继续和重置等功能。
二、介绍系统的设计界面
闹钟的布局文件代码如下
由于该闹钟系统包含时钟、闹钟、计时器、秒表四个功能,所以只要在xml文件插入TabHost控件就能实现在手机上更加简洁地展示四个功能。后面只需要在TabHost中插入四个Tab用来切换展示的界面,具体的代码实现如下:
public class MainActivity extends AppCompatActivity { ? ? private TabHost mTabHost; ? ? private StopWatchView mStopWatchView; ? ? @Override ? ? public SharedPreferences getPreferences(int mode) { ? ? ? ? return super.getPreferences(mode); ? ? } ? ? @RequiresApi(api = Build.VERSION_CODES.P) ? ? @Override ? ? protected void onCreate(Bundle savedInstanceState) { ? ? ? ? super.onCreate(savedInstanceState); ? ? ? ? setContentView(R.layout.activity_main); ? ? ? ? mTabHost = (TabHost) findViewById(R.id.tabhost); ? ? ? ? mTabHost.setup(); ? ? ? ? mTabHost.addTab(mTabHost.newTabSpec("tabTime").setIndicator("时钟").setContent(R.id.tabTime)); ? ? ? ? mTabHost.addTab(mTabHost.newTabSpec("tabAlarm").setIndicator("闹钟").setContent(R.id.tabAlarm)); ? ? ? ? mTabHost.addTab(mTabHost.newTabSpec("tabTimer").setIndicator("计时器").setContent(R.id.tabTimer)); ? ? ? ? mTabHost.addTab(mTabHost.newTabSpec("tabStopWatch").setIndicator("秒表").setContent(R.id.tabStopWatch)); ? ? ? ? mStopWatchView = (StopWatchView) findViewById(R.id.tabStopWatch); ? ? } ? ? @Override ? ? protected void onDestroy() { ? ? ? ? super.onDestroy(); ? ? ? ? mStopWatchView.onDestory(); ? ? } }
一、时钟功能
因为时钟功能中,只要显示当前的日期和时钟就可以了,所以只需要插入一个TextView用来显示日期时间就可以了。
xml文件中的代码(new 一个时钟类TimeView,把时钟一块的LinearLayout换成com.example.tsclock.TimeView)
?// 时钟 <com.example.tsclock.TimeView ? ? ?android:id="@+id/tabTime" ? ? ?android:layout_width="match_parent" ? ? ?android:layout_height="match_parent" ? ? ?android:orientation="vertical"> <TextView ? ? ? ?android:id="@+id/tvTime" ? ? ? ?android:layout_width="match_parent" ? ? ? ?android:layout_height="match_parent" ? ? ? ?android:textAppearance="?android:attr/textAppearanceLarge" ? ? ? ?android:gravity="center"/> </com.example.tsclock.TimeView>
TimeView.java
要将时间显示到TabHost中,就必须先要获取其中的id,然后通过Calendar获取当前系统的时间,最后再每过1秒钟刷新一次,这样就能够再TextView中出现时间在不停的变化。
public class TimeView extends LinearLayout { ? ? private TextView tvTime; ? ? public TimeView(Context context) { ? ? ? ? super(context); ? ? } ? ? public TimeView(Context context, @Nullable AttributeSet attrs) { ? ? ? ? super(context, attrs); ? ? } ? ? public TimeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { ? ? ? ? super(context, attrs, defStyleAttr); ? ? } ? ? // 在初始化之后进行的操作 ? ? @Override ? ? protected void onFinishInflate() { ? ? ? ? super.onFinishInflate(); ? ? ? ? tvTime = (TextView) findViewById(R.id.tvTime); ? ? ? ? // handler每秒执行一次 ? ? ? ? timerHandler.sendEmptyMessage(0); ? ? } ? ? // 可见属性发生变化之后 ? ? @Override ? ? protected void onVisibilityChanged(@NonNull View changedView, int visibility) { ? ? ? ? super.onVisibilityChanged(changedView, visibility); ? ? ? ? if (visibility == View.VISIBLE){ // 如果可见 则发送一个消息 ? ? ? ? ? ? timerHandler.sendEmptyMessage(0); ? ? ? ? }else{ ? ? ? ? ? ? ? ? ? ? ? ? ? // ?如果不可见 移除所有的消息 ? ? ? ? ? ? timerHandler.removeMessages(0); ? ? ? ? } ? ? } ? ? // 重新刷新时间 ? ? private void refreshTime(){ ? ? ? ? // 呈现一个时间对象 ? ? ? ? Calendar c = Calendar.getInstance(); ? ? ? ? // 获取时分秒 ? ? ? ? tvTime.setText(String.format("%d:%d:%d",c.get(Calendar.HOUR_OF_DAY),c.get(Calendar.MINUTE),c.get(Calendar.SECOND))); ? ? } ? ? private Handler timerHandler = new Handler() { ? ? ? ? public void handleMessage(android.os.Message msg){ ? ? ? ? ? ? // 呈现出来 ? ? ? ? ? ? refreshTime(); ? ? ? ? ? ? // 如果可见 则刷新 ? ? ? ? ? ? if (getVisibility() == View.VISIBLE){ ? ? ? ? ? ? ? ? // 1000毫秒之后再制学校handlerMessage()方法 ? ? ? ? ? ? ? ? timerHandler.sendEmptyMessageDelayed(0,1000); ? ? ? ? ? ? } ? ? ? ? } ? ? }; }
二、闹钟功能
闹钟功能就相对时钟功能就复杂很多了,因为这里需要对闹钟进行增加,删除等操作,而且可能需要展示多个闹钟的时间。所以这里需要用到有一个Button控件用来增加闹钟和一个ListView控件用来展示闹钟的时间。
xml代码
// 闹钟 <com.example.tsclock.AlarmView ? ? ? ? android:id="@+id/tabAlarm" ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="match_parent" ? ? ? ? android:orientation="vertical"> ?<ListView ? ? ? ?android:id="@+id/lvAlarmList" ? ? ? ?android:layout_width="match_parent" ? ? ? ?android:layout_weight="1" ? ? ? ?android:layout_height="0dp"> </ListView> <Button ? ? ? android:id="@+id/btnAddAlarm" ? ? ? android:layout_width="match_parent" ? ? ? android:layout_height="wrap_content" ? ? ? android:text="@string/add_alarm" ? ? ? android:textColor="#FFFFFF" ? ? ? android:background="@color/colorBlue" /> </com.example.tsclock.AlarmView>
闹钟类,AlarmView.java
需要判断时间到了需要触发事件,需要播放音乐和震动。所以播放音乐和震动放在另一个活动中(PlayAlarmAty.java )
public class AlarmView extends LinearLayout { ? ? private Button btnAddAlarm; ? ? private ListView lvAlarmList; ? ? private ArrayAdapter<AlarmData> mAdapter; ? ? private static final String KEY_ALARM_LIST = "alarmList"; ? ? // 使用系统的闹钟服务 ? ? private AlarmManager mAlarmManager; ? ? public AlarmView(Context context) { ? ? ? ? super(context); ? ? ? ? init(); ? ? } ? ? public AlarmView(Context context, @Nullable AttributeSet attrs) { ? ? ? ? super(context, attrs); ? ? ? ? init(); ? ? } ? ? private void init(){ ? ? ? ? // 使用闹钟服务设定闹钟 ? ? ? ? mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); ? ? } ? ? // 在初始化之后进行的操作 ? ? @Override ? ? protected void onFinishInflate() { ? ? ? ? super.onFinishInflate(); ? ? ? ? btnAddAlarm ?= (Button)findViewById(R.id.btnAddAlarm); ? ? ? ? lvAlarmList = (ListView) findViewById(R.id.lvAlarmList); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// 系统的简单资源 ? ? ? ? mAdapter = new ArrayAdapter<AlarmView.AlarmData>(getContext(),android.R.layout.simple_list_item_1); ? ? ? ? // 设置Adapter ? ? ? ? lvAlarmList.setAdapter(mAdapter); ? ? ? ? // 读取已经存储在SharedPreferences中的数据 ? ? ? ? readSavedAlarmList(); ? ? ? ? btnAddAlarm.setOnClickListener(new View.OnClickListener() {// 添加闹钟的点击事件 ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? addAlarm(); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? // 删除闹钟 ? ? ? ? lvAlarmList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public boolean onItemLongClick(AdapterView<?> parent, View view,final int position, long id) { ? ? ? ? ? ? ? ? new AlertDialog.Builder(getContext()).setTitle("操作选项").setItems(new CharSequence[]{"删除"}, new DialogInterface.OnClickListener() { ? ? ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? ? ? public void onClick(DialogInterface dialog, int which) { ? ? ? ? ? ? ? ? ? ? ? ? switch (which){ ? ? ? ? ? ? ? ? ? ? ? ? ? ? case 0: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? deleteAlarm(position); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? ? ? default: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? }).setNegativeButton("取消",null).show(); ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? }); ? ? } ? ? // 删除闹钟 ? ? private void deleteAlarm(int position){ ? ? ? ? AlarmData ad = mAdapter.getItem(position); ? ? ? ? // 把闹钟从闹钟列表移除 ? ? ? ? mAdapter.remove(ad); ? ? ? ? saveAlarmList(); ? ? ? ? // 移除闹钟 ? ? ? ? mAlarmManager.cancel(PendingIntent.getBroadcast(getContext(),ad.getId(),new Intent(getContext(),AlarmReceiver.class),0)); ? ? } ? ? // 添加闹钟 ? ? private void addAlarm(){ ? ? ? ? // 获取当前时间 ? ? ? ? Calendar c = Calendar.getInstance(); ? ? ? ? // 弹出一个时间的选择框 ? ? ? ? new TimePickerDialog(getContext(), new TimePickerDialog.OnTimeSetListener() { ? ? ? ? ? ? // 设置时间 ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onTimeSet(TimePicker view, int hourOfDay, int minute) { ? ? ? ? ? ? ? ? // 获取当前时间 ? ? ? ? ? ? ? ? Calendar calendar = Calendar.getInstance(); ? ? ? ? ? ? ? ? calendar.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); ? ? ? ? ? ? ? ? //需要根据API版本来判断调用,从Android4.4(API19)开始,为了节能省电(减少系统唤醒和电池使用) ? ? ? ? ? ? ? ? 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(); ? ? } ? ? // 存储数据(存到SharedPreferences中) ? ? private void saveAlarmList(){ ? ? ? ? SharedPreferences.Editor editor = getContext().getSharedPreferences(AlarmView.class.getName(),Context.MODE_PRIVATE).edit(); ? ? ? ? // 存储数据(for循环遍历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);// 输出存储的闹钟数据 ? ? ? ? }else { ? ? ? ? ? ? editor.putString(KEY_ALARM_LIST,null); ? ? ? ? } ? ? ? ? editor.commit(); ? ? } ? ? // 读取已存的数据 ? ? private void readSavedAlarmList(){ ? ? ? ? // 获取到SharedPreferences(数据内容) ? ? ? ? SharedPreferences sp = getContext().getSharedPreferences(AlarmView.class.getName(),Context.MODE_PRIVATE); ? ? ? ? String content = sp.getString(KEY_ALARM_LIST,null); ? ? ? ? // 这里需要判断,不然没闹钟数据的时候会有空指针异常 ? ? ? ? if (content != null){ ? ? ? ? ? ? //这里取得每一个闹钟的time添加到数组里 ? ? ? ? ? ? String[] timeStrings = content.split(","); ? ? ? ? ? ? // 遍历数组,把数据添加到mAdapter ? ? ? ? ? ? for (String string : timeStrings){ ? ? ? ? ? ? ? ? mAdapter.add(new AlarmData(Long.parseLong(string))); ? ? ? ? ? ? } ? ? ? ? } ? ? } ? ? //闹钟的数据,用一个类要保存,这是常用的做法 ? ? 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); ? ? ? ? } ? ? } }
当触发事件发生时,我们就要播放我们之前准备的音乐了,但是怎么播放呢,这里我们就要用到mediaPlayer媒体播放器这个函数了,这个函数主要就是用来播放音乐或者动画等。当开始播放时,我们也需要弹出警告框,提醒用户去关闭闹钟,所以这里我们需要另外编写一个类,用来执行这些功能。
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方式,创建MediaPlayer对象 ? ? ? ? mMediaPlayer.setLooping(true); // 设置是否对播放的音乐进行循环播放 ? ? ? ? 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("闹钟执行了"); ? ? ? ? // 闹钟执行一次就取消当前所执行的闹钟 ? ? ? ? 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); ? ? } }
三、秒表功能
秒表功能包含四个功能键,分别为开始,暂停、继续和重置。所以需要四个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。
有时候我们需要考虑系统的健壮性,比如当我们输入大于59的数或者是小于0的数,这时候我们需要系统检测出来,并进行修正。
需要注意的就是,当我们修改计时的时间的时候,当我们不小心将数目清空的时候,这时候就会将空指针上传,导致系统的崩溃,所以我们需要判断是不是空指针,防止越界报错。
该秒表功能有五个Button,所以需要对每个Button添加触发事件,其实startTime()函数的功能为开始计时,stopTime()函数的功能为暂停计时。所以这里需要弄清楚的就是什么时候该让那些按钮隐藏,什么时候该让那些按钮显示。
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); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? // 继续 ? ? ? ? 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不断执行刷新的操作 ? ? ? ? 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); // 每隔十毫秒执行一次 ? ? ? ? } ? ? } ? ? private void stopTimer(){ ? ? ? ? if (mTimerTask != null){ ? ? ? ? ? ? mTimerTask.cancel(); ? ? ? ? ? ? mTimerTask = null; ? ? ? ? } ? ? } ? ? // 呈现时间的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); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? // 继续 ? ? ? ? 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"); ? ? ? ? // 添加事件监听器 ? ? ? ? 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){ ? ? ? ? ? ? // 所使用时间的计数 ? ? ? ? ? ? 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执行 ? ? ? ? ? ? ? ? ? ? // 每执行一次 计数减一 ? ? ? ? ? ? ? ? ? ? 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方法每隔一秒执行一次 ? ? ? ? } ? ? } ? ? 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: ? ? ? ? ? ? ? ? ? ? // 执行弹出对话框操作 ? ? ? ? ? ? ? ? ? ? // 把时间停止(弹出一个对话框) ? ? ? ? ? ? ? ? ? ? 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; ? ? ? ? ? ? } ? ? ? ? } ? ? }; }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。
相关文章
Android中通过MediaStore获取音乐文件信息方法
这篇文章主要介绍了Android中通过MediaStore获取音乐文件信息方法,本文讲解了获取歌曲的名称、歌曲的专辑名、歌曲的歌手名、歌曲文件的全路径、歌曲文件的名称、歌曲文件的发行日期等音乐文件信息的方法,需要的朋友可以参考下2015-04-04Android自定义有限制区域的图例角度自识别涂鸦工具类完结篇
这篇文章主要为大家介绍了Android自定义有限制区域的图例角度自识别涂鸦工具类完结篇,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-02-02Android LayoutInflater.inflate源码分析
这篇文章主要介绍了Android LayoutInflater.inflate源码分析的相关资料,需要的朋友可以参考下2016-12-12
最新评论