Android开发实战闹钟项目

 更新时间:2022年09月11日 09:56:53   作者:王七鱼  
这篇文章主要介绍了Android开发实战闹钟项目,根据我们手机闹钟设计的一个闹钟APP,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云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;
? ? ? ? ? ? }
? ? ? ? }
? ? };
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。

相关文章

  • 快速解决进入fragment时不能弹出软件盘的问题

    快速解决进入fragment时不能弹出软件盘的问题

    下面小编就为大家带来一篇快速解决进入fragment时不能弹出软件盘的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • Android中通过MediaStore获取音乐文件信息方法

    Android中通过MediaStore获取音乐文件信息方法

    这篇文章主要介绍了Android中通过MediaStore获取音乐文件信息方法,本文讲解了获取歌曲的名称、歌曲的专辑名、歌曲的歌手名、歌曲文件的全路径、歌曲文件的名称、歌曲文件的发行日期等音乐文件信息的方法,需要的朋友可以参考下
    2015-04-04
  • 详解Android代码混淆实战

    详解Android代码混淆实战

    这篇文章主要介绍了详解Android代码混淆实战,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • Android实现个人资料页面头像背景模糊显示包(状态栏)

    Android实现个人资料页面头像背景模糊显示包(状态栏)

    这篇文章主要介绍了Android实现个人资料页面头像背景模糊显示包括状态栏,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-03-03
  • Android实现图片预览与保存功能

    Android实现图片预览与保存功能

    在App开发中,通常为了省流提高加载速度提升用户体验我们通常在列表中或新闻中的插图都是以缩略图压缩过的图片来进行展示,当用户点击图片时我们再去加载真正像素的大图让用户预览。本文将利用Flutter实现这一功能,需要的可以参考一下
    2022-04-04
  • Android开发之动画实现方法

    Android开发之动画实现方法

    这篇文章主要介绍了Android开发之动画实现方法,实例分析了Android中动画的原理与实现技巧,需要的朋友可以参考下
    2015-05-05
  • android ndk程序获取外置SD沙盒目录的方法讲解

    android ndk程序获取外置SD沙盒目录的方法讲解

    今天小编就为大家分享一篇android ndk程序获取外置SD沙盒目录的方法讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08
  • Android自定义有限制区域的图例角度自识别涂鸦工具类完结篇

    Android自定义有限制区域的图例角度自识别涂鸦工具类完结篇

    这篇文章主要为大家介绍了Android自定义有限制区域的图例角度自识别涂鸦工具类完结篇,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • 一文彻底了解Android中的线程和线程池

    一文彻底了解Android中的线程和线程池

    众所周知线程池能很高地提升程序的性能,下面这篇文章主要给大家介绍了关于Android中线程和线程池的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12
  • Android  LayoutInflater.inflate源码分析

    Android LayoutInflater.inflate源码分析

    这篇文章主要介绍了Android LayoutInflater.inflate源码分析的相关资料,需要的朋友可以参考下
    2016-12-12

最新评论

?


http://www.vxiaotou.com