天天看点

MY_GEEK_计时器的timer实现第一个知识点第二个知识点总结:关键还是在handler那里的更新UI,什么时候使用what字段,什么时候使用arg1,arg2字段

参考:《极客学院》

第一个知识点

分析:要用timer实现一个计时器,就必须涉及到timertask,同时还要考虑到我们在实现动态展示时间变化的时候要动态的更新UI,这里就要用到线程,我们使用handler来完成任务,下面实现一个倒计时的计时器

UI:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    tools:context="com.jikexueyuan.counttime.MainActivity" >


    <EditText 
        android:id="@+id/inputtime"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:ems="10" >
        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/gettime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="获取倒计时时间" />

    <TextView
        android:id="@+id/time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
         />

    <Button
        android:id="@+id/starttime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开始计时" />

    <Button
        android:layout_marginTop="10dp"
        android:id="@+id/stoptime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="停止计时" />

</LinearLayout>
           

java:

package com.jikexueyuan.counttime;

import java.util.Timer;


import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
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 implements OnClickListener{

    private EditText inputet;
    private Button getTime,startTime,stopTime;
    private TextView time;
    private int i = ;
    private Timer timer = null;
    private TimerTask task = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView(){
        inputet = (EditText) findViewById(R.id.inputtime);
        getTime = (Button) findViewById(R.id.gettime);
        startTime = (Button) findViewById(R.id.starttime);
        stopTime =(Button) findViewById(R.id.starttime);

        time = (TextView) findViewById(R.id.time);
        getTime.setOnClickListener(this);
        startTime.setOnClickListener(this);
        stopTime.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.gettime:
            time.setText(inputet.getText().toString());//在Textview中显示时间
            i = Integer.parseInt(inputet.getText().toString());
            break;

        case R.id.starttime:
            startTime();
            break;
        case R.id.stoptime:
            stopTime();
            break;
        default:
            break;
        }
    }
    /**
     *嗯,这里应该是最最关键的,开启线程来更新主UI
     */
    private Handler mHandler = new Handler(){
        public void handleMessage(Message msg) {
            time.setText(msg.arg1+"");
            startTime();//不断的循环更新显示
        };
    };

    public void startTime(){
        timer = new Timer();//通过该实例执行schedule方法执行任务
        task = new TimerTask() {
            @Override
            public void run() {
                i--;
                Message  message = mHandler.obtainMessage();
                message.arg1 = i;
                if(i==){
                    stopTime();
                }
                mHandler.sendMessage(message);
            }
        };
        timer.schedule(task, );//schedule方法有两种,我们使用这种只有两个参数的,注意第二个参数的意思,1代表1ms,1000代表1s变化一次
    }

    public void stopTime(){
        timer.cancel();//取消任务
    }

}
           

像这种举一反三,了解到怎么更新UI的原理就比较好办了,还有就是实现的原理就是通过自己输入的参数进行变化,当然可以随意发挥了,比如在不输入参数的情况下,顺序计时,那就将i从0开始加呗,直到手动停止才停止就OK了。

第二个知识点

安卓内部提供了非常多的API,于是找找有没有计时器的控件,嗯,没错,找到了,那就是Chronometer,下面简单的解释一下用法

UI

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent" >

    <Chronometer
        android:id="@+id/choronometer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
        <Button 
            android:id="@+id/start"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="开始计时"
            />
        <Button 
            android:id="@+id/stop"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="停止计时"
            />
        <Button 
            android:id="@+id/again"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="重置"
            />
    </LinearLayout>

</LinearLayout>
           

java

注意

setBase(long base) //设置倒计时定时器

setFormat(String format) //设置显示时间的格式

start() //开始计时

stop() //停止计时

setOnChronometerTickListener(Chronometer.OnChronometerTickListener listener) //当计时器改变时调用

package com.example.countime2;

import android.app.Activity;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Chronometer;


public class MainActivity extends Activity implements OnClickListener {
    private Chronometer chronometer=null;
    private Button startbtn,stopbtn,againbtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        chronometer=(Chronometer) findViewById(R.id.choronometer);//果然很简单
        chronometer.setFormat("计时:%s");//设定显示的格式
        startbtn.setOnClickListener(this);
        stopbtn.setOnClickListener(this);
        againbtn.setOnClickListener(this);
    }
    @Override
    public void onClick(View v){
        switch (v.getId()) {
        case R.id.start:
            chronometer.start();//人家已经做好了方法
            break;
        case R.id.stop:
            chronometer.stop();
            break;
        case R.id.again:
            chronometer.setBase(SystemClock.elapsedRealtime());//这个方法要看看后面的解释
        default:
            break;
        }
    }

}
           

总结:关键还是在handler那里的更新UI,什么时候使用what字段,什么时候使用arg1,arg2字段

  • 如果一个Message只需要拼带简单的int型信息,应优先使用Message.arg I和Message.arg2属性来传递信息,这比用Bundle更节省内存。 尽可能使用Message.what来标识信息,以便用不同方式处理Message.*