Android 计时器 (正式开启 Android 之旅)

来源:互联网 发布:在淘宝怎样买到正品 编辑:程序博客网 时间:2024/05/23 00:40

功能

  • 输入会及时显示并且检查类型错误
  • 二次输入会自动销毁已经开始的计时任务
  •  暂停后点击开始能重新开始未完成的计时任务
  • 当计时结束后,不能重复相同的计时任务,须重新输入

实现

  • 逻辑代码(若理解有误,欢迎指正
package com.damnever.counttime;/* * @Time:    14-11-22 16:41 Fri * @author:  Damnever * @Error:   Only the original thread that created a view hierarchy can touch its views. * @Reason:  只有UI线程(主线程,是线程不安全的)能更新组件,子线程(计时)不能直接更新UI组件,*冲突* * @Solution: A *Handler* allows you to send and process Message and Runnable objects associated with a thread's  *   MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When *   you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from *   that point on, it will deliver messages and runnables to that message queue and execute them as they come out *   of the message queue. *   Handler可以将子线程的消息关联到主线程的消息队列,这样主线程就能处理来自子线程的消息 */import java.util.regex.Pattern;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.text.Editable;import android.text.TextWatcher;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;public class MainActivity extends Activity {private EditText input;public TextView display;private Button startButton, stopButton;public int count = 0;private CountTime countTime;private Handler handler;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);input = (EditText) findViewById(R.id.input);display = (TextView) findViewById(R.id.time);startButton = (Button) findViewById(R.id.start_button);stopButton = (Button) findViewById(R.id.stop_button);// 设置监听器Listener l = new Listener();input.addTextChangedListener(l);startButton.setOnClickListener(l);stopButton.setOnClickListener(l);// 用于更新 UI 组件handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);display.setText(msg.what + "秒");}};}// 监听class Listener implements OnClickListener, TextWatcher {private boolean clickedStart = false;private boolean isStart = false;private CharSequence temp;// 监听按钮@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.start_button:if (!clickedStart) { // 第一次点击clickedStart = true;} else { // 非第一次点击// 第二次点击,由于每次点击开始都初始化一个线程,故将上次的线程对象置为null,让 GC 自动回收countTime = null;}try { // 捕获转型错误String t = display.getText().toString().trim();count = Integer.parseInt(t.substring(0, t.length() - 1));} catch (Exception e) {display.setText("请先设置计时时间(正整数)");break;}countTime = new CountTime(count);countTime.start();isStart = true;break;case R.id.stop_button:countTime.makePause();isStart = false;break;default:break;}}// 实时获取输入内容@Overridepublic void beforeTextChanged(CharSequence s, int start, int count,int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before,int count) {temp = s; // 保存改变时的输入框文本}// 改变后,检查文本并更新UI组件@Overridepublic void afterTextChanged(Editable s) {if (isStart) { // 如果已经开始,暂停countTime.makePause();}if (!isNum(temp.toString().trim())) {display.setText("确定是正整数? "+temp.toString());} else {display.setText(temp.toString() + "秒");}}/* 正则表达式匹配字符串是否为数字, 和 Python 相差无几 * http://www.w3cschool.cc/java/java-regular-expressions.html */private boolean isNum(String str) {Pattern pattern = Pattern.compile("^\\d+$");return pattern.matcher(str).matches();}}// 计时线程class CountTime extends Thread {private boolean pause = false;private int i;public CountTime(int count) {this.i = count;}private boolean getPause() {return this.pause;}private void makePause() {this.pause = true;}@Overridepublic void run() {while (!pause && i >= 0) {try {// handler 将消息发送到消息队列Message msg = new Message();msg.what = i;handler.sendMessage(msg);sleep(1000);this.i--; // 放在后面,防止延时} catch (InterruptedException e) {e.printStackTrace();}}}}}




  • 视图代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.damnever.counttime.MainActivity" ><EditTextandroid:id="@+id/input"android:layout_width="match_parent"android:layout_height="wrap_content"android:ems="10"android:hint="@string/input_text" ></EditText><TextViewandroid:id="@+id/time"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginBottom="10dp"android:paddingLeft="13dp"android:layout_marginTop="10dp"android:background="#cfcfcf"android:text="@string/tip"android:textColor="#ff4500"android:textSize="23dp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><Buttonandroid:id="@+id/start_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/start_button"android:layout_marginLeft="8dp" /><Buttonandroid:id="@+id/stop_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/stop_button"android:layout_marginLeft="5dp" /></LinearLayout><TextViewandroid:id="@+id/textView1"android:layout_marginTop="23dp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/info"android:textSize="15dp" /></LinearLayout>




效果


第一次使用 byzanz (Ubuntu上命令行的,泪)
0 0
原创粉丝点击