重绘TextView类演示Android的Handler Android开发技术

  今天Android123通过DigitalClock类讲解下Android平台下自绘TextView类,演示下相关的Handler、Runnable线程和Observer观察者类。首先我们回忆下上次 Android自定义View实例AnalogClock源码 一文中的自绘控件,上次主要是重写View类onDraw方法实现自己绘制,本次我们直接从TextView控件来实现自己的数字时钟控件。

  1. 将涉及Android平台UI线程的更新原理 Handler、Runnable

  2. 对于Content数据存储对象可以使用Observer观察者类来获取SQLite数据库的变化

  3. 由于本次没有改变控件的外观显示特性,所以没有重写TextView的onDraw方法,当然TextView也是从View中继承的所以可以直接调用基类的onDraw方法。Android开发网提示目前所有Android控件包android.widget.XXX都是从android.view.View类继承的。

public class DigitalClock extends TextView {

    Calendar mCalendar;
    private final static String m12 = "h:mm:ss aa";
    private final static String m24 = "k:mm:ss";
    private FormatChangeObserver mFormatChangeObserver;

    private Runnable mTicker;
    private Handler mHandler;

    private boolean mTickerStopped = false;

    String mFormat;

    public DigitalClock(Context context) {
        super(context);
        initClock(context); //资源初始化,本次为了清晰直接放到独立的initClock方法中实现。
    }

    public DigitalClock(Context context, AttributeSet attrs) {
        super(context, attrs);
        initClock(context); //同上
    }

    private void initClock(Context context) {
        Resources r = mContext.getResources();

        if (mCalendar == null) {
            mCalendar = Calendar.getInstance();
        }

        mFormatChangeObserver = new FormatChangeObserver(); //构造一个Observer
        getContext().getContentResolver().registerContentObserver(Settings.System.CONTENT_URI, true, mFormatChangeObserver); //注册该对象,用于检查小时制

        setFormat();
    }

    @Override
    protected void onAttachedToWindow() {
        mTickerStopped = false;
        super.onAttachedToWindow();
        mHandler = new Handler();

          mTicker = new Runnable() { //开一个线程获取系统时间变化,这点和上次接收action而言性能更高,可以获取到毫秒的精度

                public void run() {
                    if (mTickerStopped) return;
                    mCalendar.setTimeInMillis(System.currentTimeMillis());
                    setText(DateFormat.format(mFormat, mCalendar));
                    invalidate();
                    long now = SystemClock.uptimeMillis();
                    long next = now + (1000 – now % 1000);
                    mHandler.postAtTime(mTicker, next);
                }
            };
        mTicker.run();
    }

    @Override
    protected void onDetachedFromWindow() { //Android开发网上次的AnalogClock中已经详细讲述,这里CWJ不再赘述
        super.onDetachedFromWindow();
        mTickerStopped = true;
    }

    private boolean get24HourMode() {
        return android.text.format.DateFormat.is24HourFormat(getContext());
    }

    private void setFormat() { //设置小时制
        if (get24HourMode()) {
            mFormat = m24;
        } else {
            mFormat = m12;
        }
    }

    private class FormatChangeObserver extends ContentObserver { //Android123提示大家应该多了解下ContentObserver,用处很大
        public FormatChangeObserver() {
            super(new Handler());
        }

        @Override
        public void onChange(boolean selfChange) {
            setFormat();
        }
    }
}

  通过本次DigitalClock类的了解,可以看到Android平台的控件重绘以及消息处理很简单吧,其实本节的涉及到的Observer类可以做很多底层的事情,由于可以捕获SQLite数据库的变化,聪明的你可以想象到设计哪些安全产品了吧。

本人擅长Ai、Fw、Fl、Br、Ae、Pr、Id、Ps等软件的安装与卸载,精通CSS、JavaScript、PHP、ASP、C、C++、C#、Java、Ruby、Perl、Lisp、Python、Objective-C、ActionScript、Pascal等单词的拼写,熟悉Windows、Linux、OS X、Android、iOS、WP8等系统的开关机。

通过下面的方式来联系我们:

电邮:138762189@qq.com

联系QQ:点击这里给我发消息

官方站:www.tadke.com

※ ※ 联系请加我的企鹅号 ※※

※ ※技术支持请微信联系站长 ※※

Copyright © 2023 Tadke.com. 琼ICP备20000547号