自定义View学习小记
@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
来控制时间,StringBuffer
和很简单的算法来保存时间。
用法很简单直接在布局中引用:
<com.alu.test.okletusgo.myview.view.CountView
android:layout_width="150dp"
android:layout_height="50dp"
android:layout_centerInParent="true" />
稍加改造也可以有其他用途,例如 在抽奖之类的界面使用.
需要注意的:
在view
的点击事件里我做了:
timer = new Timer();
myTask = new MyTask();
原因是个人多次尝试,timer
的run
方法只会执行 TimerTask
类的run();
方法一次,所以手动去将之前用过的对象设置为 null
并调用 System.gc();
,企图回收对象,(感觉很笨,希望有人看了指点一下),再重新去设置一个新的 timer
。
另外提一下 View
的 invalidate();
方法需要在主线程执行 ,这也是使用了handler
的原因。
最后:
不求赞,只求提出问题,让我改进学习。
修改暂停继续的操作在 onTouch 的 ACTIONDOWN 情境下 。原因是对计时器的精准控制就应该体现在点下去的瞬间来控制跑秒。