·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> app软件开发 >> Android开发 >> Android多功能时钟开发案例(实战篇)

Android多功能时钟开发案例(实战篇)

作者:佚名      Android开发编辑:admin      更新时间:2022-07-23

上一篇为大家介绍的是Android多功能时钟开发基础内容,大家可以回顾一下,Android多功能时钟开发案例(基础篇)

接下来进入实战,快点来学习吧。

一、时钟
在布局文件中我们看到,界面上只有一个TextView,这个TextView的作用就是显示一个系统的当前时间,同时这个时间还是一秒一秒跳的,要实现一秒一秒的跳就需要我们每隔一秒就要刷新一下,同时我们这里还考虑了切换到另一个Tab的时候,这个时间就不跳动了,这样就会减少这个对系统的占用,考虑到了这点我们在这里用到了Handler,通过handler发送的msg.what 来判断是否要刷新时间。

public class TimeView extends LinearLayout { 
 
 private TextView tvTime; 
 public TimeView(Context context) { 
  super(context); 
 } 
 
 public TimeView(Context context, AttributeSet attrs) { 
  super(context, attrs); 
 } 
 
 public TimeView(Context context, AttributeSet attrs, int defStyle) { 
  super(context, attrs, defStyle); 
 } 
 
 @Override 
 protected void onFinishInflate() { 
  super.onFinishInflate(); 
  tvTime = (TextView) findViewById(R.id.tvTime); 
  //tvTime.setText("hello"); 
   
  timeHandler.sendEmptyMessage(0); 
 } 
  
 @Override 
 protected void onVisibilityChanged(View changedView, int visibility) { 
  super.onVisibilityChanged(changedView, visibility); 
  //当再次切换到这个Tab时我们就再发送一次这个消息,否者就把所有的消息移除掉 
  if (visibility == View.VISIBLE) { 
   timeHandler.sendEmptyMessage(0);    
  }else{ 
   timeHandler.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 timeHandler = new Handler(){ 
  public void handleMessage(android.os.Message msg) { 
   refreshTime(); 
    
   //处于当前Tab的时候给自己发送信息,可以刷新 
   if (getVisibility() == View.VISIBLE) {    
    //1秒钟后再次执行以下sendEmptyMessage,what参数用于区分不同的message 
    timeHandler.sendEmptyMessageDelayed(0, 1000); 
   } 
  }; 
 }; 
} 

其实这里的Handler可以用Timer来完成亦可以达到同样的效果。
在这里要提一下的是onFinishInflate(),这在我们自定义布局的时候一定要用到的,解释以及例子在之后上传的知识点中同样有,看看那个就可以了。
二、闹钟
从第二个布局中我们可以看到,我们在这里用到了一个ListView,这是用来存储我们添加的闹钟的,既然这里用到了ListView,那么我们接着就会想到要给这个ListView一个适配器adapter,因此我们会在这里创建这么一个适配器,
private ArrayAdapter<AlarmData> adapter; 
看到这里可能又会有疑问了,AlarmData这是个什么东西?有这么一个数据类型吗??其实这里我们自定义了一个数据类型,用来专门存储一下创建的闹钟时间。我们来看一下自定义的数据类型代码吧!

// 自定义数据类型 
 private static class AlarmData { 
  private long time = 0; 
  private Calendar date; 
  private String timeLabel = ""; 
 
  public AlarmData(long time) { 
   this.time = time; 
   date = Calendar.getInstance(); 
   date.setTimeInMillis(time); 
   timeLabel = String.format("%d月%d日 %d:%d", 
     date.get(Calendar.MONTH) + 1, 
     date.get(Calendar.DAY_OF_MONTH), 
     date.get(Calendar.HOUR_OF_DAY), date.get(Calendar.MINUTE)); 
  } 
 
  public long getTime() { 
   return time; 
  } 
 
  public String getTimeLabel() { 
   return timeLabel; 
  } 
 
  public int getId() { 
   return (int) (getTime() / 1000 / 60); 
  } 
 
  @Override 
  public String toString() { 
   return getTimeLabel(); 
  } 
 
 } 

这个数据类型的代码其实还是很容易明白的,不多讲了。
当我们到这里的时候,我们其实还没有真正的完成,假如我们的代码已经写好了,并且可以运行了我们运行一次后,并且添加了N个闹钟,当我们退出程序,再次打开就会发现,我们之前创建的闹钟都没了,原因是我们虽然把数据临时的保存在了ListView中,但是我们并没有长时间的保存,因此我们接着就来讲讲长久的保存这些闹钟数据。

private void saveAlarmList() { 
  Editor editor = getContext().getSharedPreferences( 
    AlarmView.class.getName(), Context.MODE_PRIVATE).edit(); 
 
  StringBuffer sb = new StringBuffer(); 
 
  for (int i = 0; i < adapter.getCount(); i++) { 
   sb.append(adapter.getItem(i).getTime()).append(","); 
  } 
  if (sb.length() > 1) { 
   String content = sb.toString().substring(0, sb.length() - 1); 
   editor.putString(KEY_ALARM_LIST, content); 
 
   System.out.println(content); 
  } else { 
   editor.putString(KEY_ALARM_LIST, null); 
  } 
  editor.commit(); 
 } 

有了保存,我们当然的会想到读取

private void readSaveAlarmList() { 
  SharedPreferences sp = getContext().getSharedPreferences( 
    AlarmView.class.getName(), Context.MODE_PRIVATE); 
  String content = sp.getString(KEY_ALARM_LIST, null); 
 
  if (content != null) { 
   String[] timeStrings = content.split(","); 
   for (String string : timeStrings) { 
    adapter.add(new AlarmData(Long.parseLong(string))); 
   } 
  } 
 } 

上面的一些陌生的类型在之后的知识点中可以查看。

接着我们来看看最关键的就是添加闹钟

private void addAlarm() { 
 
  Calendar c = Calendar.getInstance(); 
 
  new TPDiolog(getContext(), new TimePickerDialog.OnTimeSetListener() { 
 
   @Override 
   public void onTimeSet(TimePicker view, int hourOfDay, int minute) { 
 
    Calendar calendar = Calendar.getInstance(); 
    calendar.set(Calendar.HOUR_OF_DAY, hourOfDay); 
    calendar.set(Calendar.MINUTE, minute); 
    calendar.set(Calendar.SECOND, 0); 
    calendar.set(Calendar.MILLISECOND, 0); 
 
    Calendar currentTime = Calendar.getInstance(); 
    if (currentTime.getTimeInMillis() >= calendar.getTimeInMillis()) { 
     calendar.setTimeInMillis(calendar.getTimeInMillis() + 24 
       * 60 * 60 * 1000); 
    } 
    AlarmData ad = new AlarmData(calendar.getTimeInMillis()); 
    adapter.add(ad); 
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 
      ad.getTime(), 5 * 60 * 1000, PendingIntent 
        .getBroadcast(getContext(), ad.getId(), 
          new Intent(getContext(), 
            AlarmReceiver.class), 0)); 
    saveAlarmList(); 
   } 
  }, c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), true).show(); 
 } 

这里我们可以看到TPDiolog这个,当你自己尝试过后可能也会遇到同样的问题,那就是当你通过TimePickerDialog这个系统的时间选择控件的时候,点击确定后,会创建两条记录,这是因为我们点击确定后会调用该事件监听器的时间,在关闭这个Dialog的时候也会调用一次,所以我们在这里自己重写了一下该类的方法

TPDiolog.class

public class TPDiolog extends TimePickerDialog { 
 
 public TPDiolog(Context context, OnTimeSetListener callBack, int hourOfDay, 
   int minute, boolean is24HourView) { 
  super(context, callBack, hourOfDay, minute, is24HourView); 
 } 
 
 //重写该方法是为了避免调用两次onTimeSet 
 @Override 
 protected void onStop() { 
  //super.onStop(); 
 } 
} 

在之前的代码中我们还看到了一个alarmManager这一对象,这是我们为了调用系统的闹钟服务创建的实例,我们也因此而创建了一个AlarmReceiver.class

public class AlarmReceiver extends BroadcastReceiver { 
 
 @Override 
 public void onReceive(Context context, Intent arg1) { 
  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); 
  //设置intent的启动模式 
  i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
  context.startActivity(i); 
 } 
 
} 

一些小的地方讲好了,最后把AlarmView.class的完整代码贴上。

package com.example.clock; 
 
import java.util.Calendar; 
import java.util.Date; 
import java.util.Iterator; 
 
import android.app.AlarmManager; 
import android.app.AlertDialog; 
import android.app.PendingIntent; 
import android.app.TimePickerDialog; 
import android.app.TimePickerDialog.OnTimeSetListener; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.content.SharedPreferences.Editor; 
import android.util.AttributeSet; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemLongClickListener; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 
import android.widget.LinearLayout; 
import android.widget.ListView; 
import android.widget.Switch; 
import android.widget.TimePicker; 
 
public class AlarmView extends LinearLayout { 
 
 private Button btnAddAlarm; 
 private ListView lvListAlarm; 
 private ArrayAdapter<AlarmData> adapter; 
 private AlarmManager alarmManager; 
 
 public AlarmView(Context context, AttributeSet attrs, int defStyle) { 
  super(context, attrs, defStyle); 
  init(); 
 } 
 
 public AlarmView(Context context, AttributeSet attrs) { 
  super(context, attrs); 
  init(); 
 } 
 
 public AlarmView(Context context) { 
  super(context); 
  init(); 
 } 
 
 private void init() { 
  alarmManager = (AlarmManager) getContext().getSystemService( 
    Context.ALARM_SERVICE); 
 } 
 
 @Override 
 protected void onFinishInflate() { 
  super.onFinishInflate(); 
  btnAddAlarm = (Button) findViewById(R.id.btnAddAlarm); 
  lvListAlarm = (ListView) findViewById(R.id.lvListAlarm); 
 
  adapter = new ArrayAdapter<AlarmData>(getContext(), 
    android.R.layout.simple_list_item_1); 
  lvListAlarm.setAdapter(adapter); 
 
  readSaveAlarmList(); 
  // adapter.add(new AlarmData(System.currentTimeMillis())); 
 
  btnAddAlarm.setOnClickListener(new OnClickListener() { 
 
   @Override 
   public void onClick(View v) { 
    addAlarm(); 
   } 
  }); 
  // 长按某项删除 
  lvListAlarm.setOnItemLongClickListener(new OnItemLongClickListener() { 
 
   @Override 
   public boolean onItemLongClick(AdapterView<?> arg0, View arg1, 
     final int position, long arg3) { 
 
    new AlertDialog.Builder(getContext()) 
      .setTitle("操作选项") 
      .setItems(new CharSequence[] { "删除", "删除1" }, 
        new DialogInterface.OnClickListener() { 
 
         @Override 
         public void onClick(DialogInterface dialog, 
           int which) { 
          switch (which) { 
          case 0: 
           deleteAlarm(position); 
           break; 
 
          default: 
           break; 
          } 
         } 
        }).setNegativeButton("取消", null).show(); 
    return true; 
   } 
  }); 
 } 
 
 private void deleteAlarm(int position) { 
  AlarmData ad = adapter.getItem(position); 
  adapter.remove(ad); 
  saveAlarmList(); 
 
  alarmManager.cancel(PendingIntent.getBroadcast(getContext(), 
    ad.getId(), new Intent(getContext(), AlarmReceiver.class), 0)); 
 } 
 
 private void addAlarm() { 
 
  Calendar c = Calendar.getInstance(); 
 
  new TPDiolog(getContext(), new TimePickerDialog.OnTimeSetListener() { 
 
   @Override 
   public void onTimeSet(TimePicker view, int hourOfDay, int minute) { 
 
    Calendar calendar = Calendar.getInstance(); 
    calendar.set(Calendar.HOUR_OF_DAY, hourOfDay); 
    calendar.set(Calendar.MINUTE, minute); 
    calendar.set(Calendar.SECOND, 0); 
    calendar.set(Calendar.MILLISECOND, 0); 
 
    Calendar currentTime = Calendar.getInstance(); 
    if (currentTime.getTimeInMillis() >= calendar.getTimeInMillis()) { 
     calendar.setTimeInMillis(calendar.getTimeInMillis() + 24 
       * 60 * 60 * 1000); 
    } 
    AlarmData ad = new AlarmData(calendar.getTimeInMillis()); 
    adapter.add(ad); 
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 
      ad.getTime(), 5 * 60 * 1000, PendingIntent 
        .getBroadcast(getContext(), ad.getId(), 
          new Intent(getContext(), 
            AlarmReceiver.class), 0)); 
    saveAlarmList(); 
   } 
  }, c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), true).show(); 
 } 
 
 private static final String KEY_ALARM_LIST = "alarmlist"; 
 
 private void saveAlarmList() { 
  Editor editor = getContext().getSharedPreferences( 
    AlarmView.class.getName(), Context.MODE_PRIVATE).edit(); 
 
  StringBuffer sb = new StringBuffer(); 
 
  for (int i = 0; i < adapter.getCount(); i++) { 
   sb.append(adapter.getItem(i).getTime()).append(","); 
  } 
  if (sb.length() > 1) { 
   String content = sb.toString().substring(0, sb.length() - 1); 
   editor.putString(KEY_ALARM_LIST, content); 
 
   System.out.println(content); 
  } else { 
   editor.putString(KEY_ALARM_LIST, null); 
  } 
  editor.commit(); 
 } 
 
 private void readSaveAlarmList() { 
  SharedPreferences sp = getContext().getSharedPreferences( 
    AlarmView.class.getName(), Context.MODE_PRIVATE); 
  String content = sp.getString(KEY_ALARM_LIST, null); 
 
  if (content != null) { 
   String[] timeStrings = content.split(","); 
   for (String string : timeStrings) { 
    adapter.add(new AlarmData(Long.parseLong(string))); 
   } 
  } 
 } 
 
 // 自定义数据类型 
 private static class AlarmData { 
  private long time = 0; 
  private Calendar date; 
  private String timeLabel = ""; 
 
  public AlarmData(long time) { 
   this.time = time; 
   date = Calendar.getInstance(); 
   date.setTimeInMillis(time); 
   timeLabel = String.format("%d月%d日 %d:%d", 
     date.get(Calendar.MONTH) + 1, 
     date.get(Calendar.DAY_OF_MONTH), 
     date.get(Calendar.HOUR_OF_DAY), date.get(Calendar.MINUTE)); 
  } 
 
  public long getTime() { 
   return time; 
  } 
 
  public String getTimeLabel() { 
   return timeLabel; 
  } 
 
  public int getId() { 
   return (int) (getTime() / 1000 / 60); 
  } 
 
  @Override 
  public String toString() { 
   return getTimeLabel(); 
  } 
 
 } 
} 

三、计时器
计时器的主要功能就是你先设定一个时间,然后点击开始,时间就会一秒一秒的减少,在这里我么主要用到了Timer这个系统的计时器,这代码中没有上面难懂的地方,有些地方已经给上注释了,所以直接贴代码,可能有些人会不知道Timer怎么用,之后的知识点中都会有提到。

package com.example.clock; 
 
import java.util.Timer; 
import java.util.TimerTask; 
 
import android.R.integer; 
import android.app.AlertDialog; 
import android.content.Context; 
import android.os.Handler; 
import android.text.Editable; 
import android.text.TextUtils; 
import android.text.TextWatcher; 
import android.util.AttributeSet; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.LinearLayout; 
 
public class TimerView extends LinearLayout { 
 
 public TimerView(Context context, AttributeSet attrs) { 
  super(context, attrs); 
 } 
 
 public TimerView(Context context) { 
  super(context); 
 } 
 
 @Override 
 protected void onFinishInflate() { 
  super.onFinishInflate(); 
 
  btnStart = (Button) findViewById(R.id.btnStart); 
  btnPause = (Button) findViewById(R.id.btnPause); 
  btnResume = (Button) findViewById(R.id.btnResume); 
  btnReset = (Button) findViewById(R.id.btnReset); 
 
  btnStart.setOnClickListener(new OnClickListener() { 
 
   @Override 
   public void onClick(View v) { 
    startTimer(); 
    btnStart.setVisibility(View.GONE); 
    btnPause.setVisibility(View.VISIBLE); 
    btnReset.setVisibility(View.VISIBLE); 
   } 
  }); 
   
  btnPause.setOnClickListener(new OnClickListener() { 
    
   @Override 
   public void onClick(View v) { 
    stopTimer(); 
    btnPause.setVisibility(View.GONE); 
    btnResume.setVisibility(View.VISIBLE); 
   } 
  }); 
   
  btnResume.setOnClickListener(new OnClickListener() { 
    
   @Override 
   public void onClick(View v) { 
    startTimer(); 
    btnPause.setVisibility(View.VISIBLE); 
    btnResume.setVisibility(View.GONE); 
   } 
  }); 
  btnReset.setOnClickListener(new OnClickListener() { 
    
   @Override 
   public void onClick(View v) { 
    stopTimer(); 
    etHour.setText("00"); 
    etMin.setText("00"); 
    etSec.setText("00"); 
     
    btnReset.setVisibility(View.GONE); 
    btnResume.setVisibility(View.GONE); 
    btnPause.setVisibility(View.GONE); 
    btnStart.setVisibility(View.VISIBLE); 
   } 
  }); 
 
  etHour = (EditText) findViewById(R.id.etHour); 
  etMin = (EditText) findViewById(R.id.etMin); 
  etSec = (EditText) findViewById(R.id.etSec); 
 
  etHour.setText("00"); 
  etHour.addTextChangedListener(new TextWatcher() { 
 
   @Override 
   public void onTextChanged(CharSequence s, int start, int before, 
     int count) { 
    /* 
     * 这个方法是在Text改变过程中触发调用的, 它的意思就是说在原有的文本s中, 
     * 从start开始的count个字符替换长度为before的旧文本, 
     * 注意这里没有将要之类的字眼,也就是说一句执行了替换动作。 
     */ 
    if (!TextUtils.isEmpty(s)) { 
 
     int value = Integer.parseInt(s.toString()); 
 
     if (value > 59) { 
      etHour.setText("59"); 
     } else if (value < 0) { 
      etHour.setText("00"); 
     } 
    } 
    checkToEnableBtnStart(); 
   } 
 
   @Override 
   public void beforeTextChanged(CharSequence s, int start, int count, 
     int after) { 
   } 
 
   @Override 
   public void afterTextChanged(Editable s) { 
   } 
  }); 
  etMin.setText("00"); 
  etMin.addTextChangedListener(new TextWatcher() { 
 
   @Override 
   public void onTextChanged(CharSequence s, int start, int before, 
     int count) { 
    if (!TextUtils.isEmpty(s)) { 
 
     int value = Integer.parseInt(s.toString()); 
 
     if (value > 59) { 
      etMin.setText("59"); 
     } else if (value < 0) { 
      etMin.setText("00"); 
     } 
    } 
    checkToEnableBtnStart(); 
   } 
 
   @Override 
   public void beforeTextChanged(CharSequence s, int start, int count, 
     int after) { 
   } 
 
   @Override 
   public void afterTextChanged(Editable s) { 
   } 
  }); 
  etSec.setText("00"); 
  etSec.addTextChangedListener(new TextWatcher() { 
 
   @Override 
   public void onTextChanged(CharSequence s, int start, int before, 
     int count) { 
    if (!TextUtils.isEmpty(s)) { 
 
     int value = Integer.parseInt(s.toString()); 
 
     if (value > 59) { 
      etSec.setText("59"); 
     } else if (value < 0) { 
      etSec.setText("00"); 
     } 
    } 
    checkToEnableBtnStart(); 
   } 
 
   @Override 
   public void beforeTextChanged(CharSequence s, int start, int count, 
     int after) { 
   } 
 
   @Override 
   public void afterTextChanged(Editable s) { 
   } 
  }); 
 
  btnStart.setVisibility(View.VISIBLE); 
  btnStart.setEnabled(false); 
  btnPause.setVisibility(View.GONE); 
  btnResume.setVisibility(View.GONE); 
  btnReset.setVisibility(View.GONE); 
 } 
 
 private void checkToEnableBtnStart() { 
  btnStart.setEnabled((!TextUtils.isEmpty(etHour.getText()) && Integer 
    .parseInt(etHour.getText().toString()) > 0) 
    || (!TextUtils.isEmpty(etMin.getText()) && Integer 
      .parseInt(etMin.getText().toString()) > 0) 
    || (!TextUtils.isEmpty(etSec.getText()) && Integer 
      .parseInt(etSec.getText().toString()) > 0)); 
 } 
 
 private void startTimer() { 
  if (timerTask == null) { 
   allTimeCount = Integer.parseInt(etHour.getText().toString()) * 60 
     * 60 + Integer.parseInt(etMin.getText().toString()) * 60 
     + Integer.parseInt(etSec.getText().toString()); 
   timerTask = new TimerTask() { 
 
    @Override 
    public void run() { 
     allTimeCount--; 
     handle.sendEmptyMessage(MSG_WHAT_TIME_TICK); 
     if (allTimeCount <= 0) { 
      handle.sendEmptyMessage(MSG_WHAT_TIME_IS_UP); 
      stopTimer(); 
     } 
    } 
   }; 
   timer.schedule(timerTask, 1000, 1000); 
  } 
 } 
 private void stopTimer(){ 
  if (timerTask!=null) { 
   timerTask.cancel(); 
   timerTask=null; 
  } 
 } 
 
 private Handler handle = new Handler(){ 
   
  public void handleMessage(android.os.Message msg) { 
   switch (msg.what) { 
   case MSG_WHAT_TIME_TICK: 
    int hour = allTimeCount/60/60; 
    int min = (allTimeCount/60)%60; 
    int sec = allTimeCount%60; 
     
    etHour.setText(hour+""); 
    etMin.setText(min+""); 
    etSec.setText(sec+""); 
    break; 
     
   case MSG_WHAT_TIME_IS_UP:  
    new AlertDialog.Builder(getContext()) 
    .setTitle("Time is up!") 
    .setMessage("Time is up!") 
    .setNegativeButton("Cancle", null).show(); 
     
    btnReset.setVisibility(View.GONE); 
    btnResume.setVisibility(View.GONE); 
    btnPause.setVisibility(View.GONE); 
    btnStart.setVisibility(View.VISIBLE); 
    break; 
 
   default: 
    break; 
   } 
  }; 
 }; 
 private static final int MSG_WHAT_TIME_IS_UP = 1; 
 private static final int MSG_WHAT_TIME_TICK = 2; 
  
 private int allTimeCount = 0; 
 private Timer timer = new Timer(); 
 private TimerTask timerTask = null; 
 private Button btnStart, btnPause, btnResume, btnReset; 
 private EditText etHour, etMin, etSec; 
 
} 

四、秒表
最后的秒表相信大家都不陌生,用到的知识正好之前的三个都有讲到,只要明白前三个后,这个就不难理解了。

package com.example.clock; 
 
import java.util.ArrayList; 
import java.util.Timer; 
import java.util.TimerTask; 
 
import android.content.Context; 
import android.os.Handler; 
import android.util.AttributeSet; 
import android.view.View; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 
import android.widget.LinearLayout; 
import android.widget.ListView; 
import android.widget.TextView; 
 
public class StopWatchView extends LinearLayout { 
 
 private TextView tvHour,tvMin,tvSec,tvMsec; 
 private Button btnStart,btnPause,btnResume,btnReset,btnLap; 
 private ListView lvTimeList; 
 private ArrayAdapter<String> adapter; 
 public StopWatchView(Context context, AttributeSet attrs) { 
  super(context, attrs); 
 } 
 
 @Override 
 protected void onFinishInflate() { 
  super.onFinishInflate(); 
   
  tvHour = (TextView) findViewById(R.id.timeHour); 
  tvHour.setText("0"); 
  tvMin = (TextView) findViewById(R.id.timeMin); 
  tvMin.setText("0"); 
  tvSec = (TextView) findViewById(R.id.timeSec); 
  tvSec.setText("0"); 
  tvMsec = (TextView) findViewById(R.id.timeMsec); 
  tvMsec.setText("0"); 
   
  btnStart = (Button) findViewById(R.id.btnSWStart); 
  btnPause = (Button) findViewById(R.id.btnSWPause); 
  btnResume = (Button) findViewById(R.id.btnSWResume); 
  btnLap = (Button) findViewById(R.id.btnSWLap); 
  btnReset = (Button) findViewById(R.id.btnSWReset); 
   
  btnStart.setOnClickListener(new OnClickListener() { 
    
   @Override 
   public void onClick(View v) { 
    startTimer(); 
    btnStart.setVisibility(View.GONE); 
    btnPause.setVisibility(View.VISIBLE); 
    btnLap.setVisibility(View.VISIBLE); 
   } 
  }); 
  btnPause.setOnClickListener(new OnClickListener() { 
    
   @Override 
   public void onClick(View v) { 
    stopTimer(); 
    btnPause.setVisibility(View.GONE); 
    btnResume.setVisibility(View.VISIBLE); 
    btnLap.setVisibility(View.GONE); 
    btnReset.setVisibility(View.VISIBLE); 
   } 
  }); 
  btnResume.setOnClickListener(new OnClickListener() { 
    
   @Override 
   public void onClick(View v) { 
    startTimer(); 
    btnResume.setVisibility(View.GONE); 
    btnPause.setVisibility(View.VISIBLE); 
    btnLap.setVisibility(View.VISIBLE); 
    btnReset.setVisibility(View.GONE); 
   } 
  }); 
  btnReset.setOnClickListener(new OnClickListener() { 
    
   @Override 
   public void onClick(View v) { 
    stopTimer(); 
    tenMSecs = 0; 
    adapter.clear(); 
    btnReset.setVisibility(View.GONE); 
    btnLap.setVisibility(View.GONE); 
    btnPause.setVisibility(View.GONE); 
    btnResume.setVisibility(View.GONE); 
    btnStart.setVisibility(View.VISIBLE); 
   } 
  }); 
  btnLap.setOnClickListener(new OnClickListener() { 
    
   @Override 
   public void onClick(View v) { 
    adapter.insert(String.format("%d:%d:%d.%d", tenMSecs/100/60/60,tenMSecs/100/60%60,tenMSecs/100%60,tenMSecs%100), 0); 
   } 
  }); 
  btnLap.setVisibility(View.GONE); 
  btnPause.setVisibility(View.GONE); 
  btnResume.setVisibility(View.GONE); 
  btnReset.setVisibility(View.GONE); 
   
  lvTimeList = (ListView) findViewById(R.id.lvWatchTime); 
  adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1); 
  lvTimeList.setAdapter(adapter); 
   
  showTimerTask = new TimerTask() { 
    
   @Override 
   public void run() { 
    handle.sendEmptyMessage(MSG_WHAT_SHOW_TIME); 
   } 
  }; 
  timer.schedule(showTimerTask, 200, 200); 
 } 
  
 private void startTimer(){ 
  if (timerTask == null) { 
   timerTask = new TimerTask() { 
     
    @Override 
    public void run() { 
     tenMSecs++; 
    } 
   }; 
   timer.schedule(timerTask, 10, 10); 
  } 
 } 
 private void stopTimer(){ 
  if (timerTask != null) { 
   timerTask.cancel(); 
   timerTask = null; 
  } 
 } 
  
 private int tenMSecs = 0; 
 private Timer timer =new Timer(); 
 private TimerTask timerTask = null; 
 private TimerTask showTimerTask = null; 
 private static final int MSG_WHAT_SHOW_TIME = 1; 
  
 private Handler handle = new Handler(){ 
  public void handleMessage(android.os.Message msg) { 
   switch (msg.what) { 
   case MSG_WHAT_SHOW_TIME: 
    tvHour.setText(tenMSecs/100/60/60+""); 
    tvMin.setText(tenMSecs/100/60%60+""); 
    tvSec.setText(tenMSecs/100%60+""); 
    tvMsec.setText(tenMSecs%100+""); 
    break; 
 
   default: 
    break; 
   } 
  }; 
 }; 
 public void onDestroy() { 
  timer.cancel(); 
 } 
  
} 

到此为止,自己的第一个实战算是完成了,但是就是界面很low,这个只是把基本的功能实现了,但是在界面上没有做很大的完善,在之后的实战中会慢慢改进的。

源码下载:Android多功能时钟

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