Android 开发第六弹:简易时钟(计时器)

来源:互联网 发布:egd网络黄金是否合法 编辑:程序博客网 时间:2024/05/16 01:40

接上篇Android 开发第五弹:简易时钟(闹钟) ,这次是一个时钟类应用,目前依旧是主要的功能,长得还是很挫。当然了,核心功能是有的……

这里写图片描述

时钟

先把简单的时钟给列出来吧,这里都写的很简单,即便要用世界各个城市的话,也只是相应的加上或减去几个小时。

新建TimeView类,并扩展自LinearLayout,然后布局文件和上一篇中那么写就好了。

<myapplication.nomasp.com.clock.TimeView    android : id = "@+id/tabTime"    android : layout_width = "match_parent"    android : layout_height = "match_parent"    android : orientation = "vertical">    <TextView        android : id = "@+id/tvTime"        android : textAppearance = "?android:attr/textAppearanceLarge"        android : layout_width = "match_parent"        android : layout_height = "match_parent"        android : gravity = "center" / ></myapplication.nomasp.com.clock.TimeView>
    // 实例化TextView控件    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 defStyleAttr) {        super(context, attrs, defStyleAttr);    }    @Override    protected void onFinishInflate(){        super.onFinishInflate();        tvTime = (TextView)findViewById(R.id.tvTime);        tvTime.setText("H");        timeHandler.sendEmptyMessage(0);    }    private Handler timeHandler = new Handler() {        public void handleMessage(Message msg){            // 刷新时间            refreshTime();            if(getVisibility() == View.VISIBLE){                timeHandler.sendEmptyMessageDelayed(0, 1000);            }        }    };    // 刷新时间    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)));    }    @Override    protected void onVisibilityChanged(View changedView, int visibility) {        super.onVisibilityChanged(changedView, visibility);        if(visibility == View.VISIBLE){            timeHandler.sendEmptyMessage(0);        }else{            timeHandler.removeMessages(0);        }    }

就这些了,下面正式开始计时器的部分。

TimerView

TimerView类同样是扩展自LinearLayout,并且布局的写法也是如出一辙:

<myapplication.nomasp.com.clock.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 = "wrap_content">    <EditText        android : id = "@+id/etHour"        android : inputType = "number"        android : textAppearance = "?android:attr/textAppearanceLarge"        android : layout_width = "0dp"        android : layout_height = "wrap_content"        android : layout_weight = "1"        android : singleLine = "true" / >        android:singleLine = "true" / >    <TextView        android : textAppearance = "?android:attr/textAppearanceLarge"        android : layout_width = "wrap_content"        android : layout_height = "wrap_content"        android : text = ":" / >    <EditText        android : id = "@+id/etMinute"        android : inputType = "number"        android : textAppearance = "?android:attr/textAppearanceLarge"        android : layout_width = "0dp"        android : layout_height = "wrap_content"        android : layout_weight = "1"        android : singleLine = "true" / >    <TextView        android : textAppearance = "?android:attr/textAppearanceLarge"        android : layout_width = "wrap_content"        android : layout_height = "wrap_content"        android : text = ":" / >    <EditText        android : id = "@+id/etSecond"        android : inputType = "number"        android : textAppearance = "?android:attr/textAppearanceLarge"        android : layout_width = "0dp"        android : layout_height = "wrap_content"        android : layout_weight = "1"        android : singleLine = "true" / >    < / LinearLayout>    <LinearLayout        android : id = "@+id/llBtnGroup"        android : layout_width = "match_parent"        android : layout_height = "wrap_content"        android : orientation = "horizontal">    <Button        android : id = "@+id/btnStart"        android : layout_width = "0dp"        android : layout_height = "wrap_content"        android : layout_weight = "1"        android : text = "@string/start" / >    <Button        android : id = "@+id/btnPause"        android : layout_width = "0dp"        android : layout_height = "wrap_content"        android : layout_weight = "1"        android : text = "@string/pause" / >    <Button        android : id = "@+id/btnResume"        android : layout_width = "0dp"        android : layout_height = "wrap_content"        android : layout_weight = "1"        android : text = "@string/resume" / >    <Button        android : id = "@+id/btnReset"        android : layout_width = "0dp"        android : layout_height = "wrap_content"        android : layout_weight = "1"        android : text = "@string/reset" / >    < / LinearLayout></myapplication.nomasp.com.clock.TimerView>

先把该定义的都定义好了:

    private Button btnStart, btnPause, btnResume, btnReset;    private EditText etHour, etMinute, etSecond;    private static final int MSG_WHAT_TIME_IS_UP = 1;    private static final int MSG_WHAT_TIME_TICK = 2;    // 所有时间计数    private int allTimerCount = 0;    private Timer timer = new Timer();    private TimerTask timerTask = null;    public TimerView(Context context) {        super(context);    }    public TimerView(Context context, AttributeSet attrs) {        super(context, attrs);    }    public TimerView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }

核心部分,首先给各个按钮设置监听,其中的点击分别实现相应的功能,并且设置相应的可见度,还要为每个EditText设置一个动态的判断,使其值不大于59也不小于0。

@Override    protected void onFinishInflate(){        super.onFinishInflate();        // 暂停        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);            }        });        // 重置        btnReset = (Button)findViewById(R.id.btnReset);        btnReset.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                stopTimer();                etHour.setText("0");                etMinute.setText("0");                etSecond.setText("0");                btnReset.setVisibility(View.GONE);                btnResume.setVisibility(View.GONE);                btnPause.setVisibility(View.GONE);                btnStart.setVisibility(View.VISIBLE);            }        });        // 恢复        btnResume = (Button)findViewById(R.id.btnResume);        btnResume.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                startTime();                btnResume.setVisibility(View.GONE);                btnPause.setVisibility(View.VISIBLE);            }        });        // 开始        btnStart = (Button)findViewById(R.id.btnStart);        btnStart.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                startTime();                btnStart.setVisibility(View.GONE);                btnPause.setVisibility(View.VISIBLE);                btnReset.setVisibility(View.VISIBLE);            }        });        etHour = (EditText)findViewById(R.id.etHour);        etMinute = (EditText)findViewById(R.id.etMinute);        etSecond = (EditText)findViewById(R.id.etSecond);        // 对每一个EditText实例都作判断,值不可以大于59或小于0        etHour.setText("00");        etHour.addTextChangedListener(new TextWatcher() {            @Override            public void beforeTextChanged(CharSequence s, int start, int count, int after) {            }            @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 afterTextChanged(Editable s) {            }        });        etMinute.setText("00");        etMinute.addTextChangedListener(new TextWatcher() {            @Override            public void beforeTextChanged(CharSequence s, int start, int count, int after) {            }            @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) {                        etMinute.setText("59");                    } else if (value < 0) {                        etMinute.setText("0");                    }                }                checkToEnableBtnStart();            }            @Override            public void afterTextChanged(Editable s) {            }        });        etSecond.setText("00");        etSecond.addTextChangedListener(new TextWatcher() {            @Override            public void beforeTextChanged(CharSequence s, int start, int count, int after) {            }            @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){                        etSecond.setText("59");                    }else if(value < 0){                        etSecond.setText("0");                    }                }                checkToEnableBtnStart();            }            @Override            public void afterTextChanged(Editable s) {            }        });        btnStart.setVisibility(View.VISIBLE);        btnPause.setVisibility(View.GONE);        btnResume.setVisibility(View.GONE);        btnReset.setVisibility(View.GONE);    }

判断是否可以开始计数,每个输入框都不能小于等于0更不能为空。

// 判断是否可以开始    private void checkToEnableBtnStart(){        btnStart.setEnabled((!TextUtils.isEmpty(etHour.getText())                && Integer.parseInt(etHour.getText().toString()) > 0) ||                (!TextUtils.isEmpty(etMinute.getText())                        && Integer.parseInt(etMinute.getText().toString()) > 0) ||                (!TextUtils.isEmpty(etSecond.getText())                        && Integer.parseInt(etSecond.getText().toString()) > 0));    }

接下来就可以开始计时了。

    // 开始    private void startTime(){        if(timerTask == null){            // 从三个输入框中获取需要计数的总秒数            allTimerCount = Integer.parseInt(etHour.getText().toString())*60*60                    + Integer.parseInt(etMinute.getText().toString())*60                    + Integer.parseInt(etSecond.getText().toString());            timerTask = new TimerTask() {                @Override                // 执行计数,allTimerCount自减                public void run() {                    allTimerCount-- ;                    handler.sendEmptyMessage(MSG_WHAT_TIME_TICK);                    // 如果剩下的所有计数已经小于0,通知handler停止                    if(allTimerCount <= 0){                        handler.sendEmptyMessage(MSG_WHAT_TIME_IS_UP);                        stopTimer();                    }                }            };            // 设置scedule,开始时间以及时间间隔,间隔此处为1秒            timer.schedule(timerTask,1000,1000);        }    }

当然除了开始计时外,也需要能够停止计时。

    // 停止计时    private void stopTimer(){        if(timerTask != null){            timerTask.cancel();            timerTask = null;        }    }

接下来就是Handler了,也不算难,多写几遍就会了。

    private Handler handler = new Handler() {        public void handleMessage(Message msg){            switch (msg.what){                case MSG_WHAT_TIME_TICK:                    // 获取时间                    int hour = allTimerCount/60/60;                    int min = (allTimerCount/60)%60;                    int sec = allTimerCount%60;                    // 将时间写到对应的EditText上                    etHour.setText(hour + "");                    etMinute.setText(min + "");                    etSecond.setText(sec + "");                    break;                case MSG_WHAT_TIME_IS_UP:                    // 弹出对话框进行提示,包括标题、消息、返回按钮                    new AlertDialog.Builder(getContext()).setTitle("Time is up")                            .setMessage("Message: Time is up")                            .setNegativeButton("Cancel",null)                            .show();                    // 设置相应的可见与否                    btnReset.setVisibility(View.GONE);                    btnResume.setVisibility(View.GONE);                    btnPause.setVisibility(View.GONE);                    btnStart.setVisibility(View.VISIBLE);                    break;                default:                    break;            }        }    };

结束

这是第二篇,还有一篇比较短的了, Android 开发第七弹:简易时钟(秒表)……

需要代码的话,直接评论留邮箱吧,我就不上传到CSDN资源了。代码会继续更新的,注释也会继续更新……

项目也上传到Github了,欢迎大家贡献代码啊——传送门 。

2 0
原创粉丝点击