自定義view實(shí)現(xiàn)簡(jiǎn)單的計(jì)時(shí)器

自定義View學(xué)習(xí)小記

@Alu

先貼代碼

public class CountView extends View {
private Paint mPaint;
private int millisecond;
private int hour;
private int minute;
private int second;
private Rect mBounds;
private Context context;
private boolean isRunning = false;
private Timer timer;
private StringBuffer stringBuffer;
private MyTask myTask;

public CountView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
    mBounds = new Rect();
    mPaint = new Paint();
    stringBuffer = new StringBuffer();
    stringBuffer.append("00:00:00:00");

}
@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()){
        case MotionEvent.ACTION_DOWN:
            if (isRunning) {
                timer.cancel();
                timer.purge();
                timer = null;
                myTask = null;
                System.gc();
            } else {
                timer = new Timer();
                myTask = new MyTask();
                timer.schedule(myTask, 0, 10);
            }
            isRunning = !isRunning;
            break;
    }
    return false;
}
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    mPaint.setColor(ContextCompat.getColor(context, R.color.colorPrimary));
    canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);
    mPaint.setColor(Color.WHITE);
    mPaint.setTextSize(60);
    String text = stringBuffer.toString();
    mPaint.getTextBounds(text, 0, text.length(), mBounds);
    float textWidth = mBounds.width();
    float textHeight = mBounds.height();
    canvas.drawText(text, getWidth() / 2 - textWidth / 2, getHeight() / 2 + textHeight / 2, mPaint);

}

private class MyTask extends TimerTask {

    @Override
    public void run() {
        stringBuffer.delete(0, stringBuffer.length());
        millisecond++;
        if (millisecond > 99) {
            millisecond = 0;
            second++;
        }
        if (second > 59) {
            second = 0;
            minute++;
        }

        if (minute > 59) {
            minute = 0;
            hour++;
        }
        if (hour < 10)
            stringBuffer.append(0).append(hour);
        else
            stringBuffer.append(hour);
        stringBuffer.append(":");
        if (minute < 10)
            stringBuffer.append(0).append(minute);
        else
            stringBuffer.append(minute);
        stringBuffer.append(":");
        if (second < 10)
            stringBuffer.append(0).append(second);
        else
            stringBuffer.append(second);
        stringBuffer.append(":");
        if (millisecond < 10)
            stringBuffer.append(0).append(millisecond);
        else
            stringBuffer.append(millisecond);
        handler.sendEmptyMessage(0);
    }

}

private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        if (msg.what == 0) {
            invalidate();
        }
    }
};

}
利用Handler+Timer來(lái)控制時(shí)間,StringBuffer和很簡(jiǎn)單的算法來(lái)保存時(shí)間。
用法很簡(jiǎn)單直接在布局中引用:

<com.alu.test.okletusgo.myview.view.CountView
    android:layout_width="150dp"
    android:layout_height="50dp"
    android:layout_centerInParent="true" />

稍加改造也可以有其他用途,例如 在抽獎(jiǎng)之類的界面使用.

需要注意的:

view的點(diǎn)擊事件里我做了:

timer = new Timer();  
myTask = new MyTask();

原因是個(gè)人多次嘗試,timerrun方法只會(huì)執(zhí)行 TimerTask 類的run();方法一次,所以手動(dòng)去將之前用過(guò)的對(duì)象設(shè)置為 null 并調(diào)用 System.gc(); ,企圖回收對(duì)象,(感覺(jué)很笨,希望有人看了指點(diǎn)一下),再重新去設(shè)置一個(gè)新的 timer。
另外提一下 Viewinvalidate(); 方法需要在主線程執(zhí)行 ,這也是使用了handler的原因。

最后:

不求贊,只求提出問(wèn)題,讓我改進(jìn)學(xué)習(xí)。

修改暫停繼續(xù)的操作在 onTouch 的 ACTIONDOWN 情境下 。原因是對(duì)計(jì)時(shí)器的精準(zhǔn)控制就應(yīng)該體現(xiàn)在點(diǎn)下去的瞬間來(lái)控制跑秒。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 主要思路 1.我們需要自定義一個(gè)繼承自FrameLayout的布局,利用FrameLayout布-局的特性(在同一...
    ZebraWei閱讀 2,803評(píng)論 0 5
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,324評(píng)論 25 708
  • 周五,我一直在說(shuō)服自己,只要你想做,就一定能做到。但是發(fā)現(xiàn)自己執(zhí)行力太差,是沒(méi)有精神,還是年齡大了,注意力渙散?,F(xiàn)...
    向往的1991閱讀 162評(píng)論 0 0
  • 開工一張新的,有誰(shuí)知道是什么名號(hào)嗎?
    joyyang1221閱讀 244評(píng)論 0 2
  • 我們沒(méi)有義務(wù)去感同身受別人的故事和感情 生活,就應(yīng)該在不傷害他人的基礎(chǔ)上 讓自己活的舒服
    樹郵閱讀 306評(píng)論 0 1

友情鏈接更多精彩內(nèi)容