View编程(2): invalidate()再探

博客Android(四) :更新UI的方法中提到invalidate()方法,但是由于自己的阅历不足,没有过多的说明,只是泛泛而谈!本篇继续探究这个诡异的方法。

在阅读本篇博客之前,建议您先看看View编程(1): Window、View与setContentView()

基于Android(四) :更新UI的方法中的例子,稍作修改:

package mark.zhang; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; import android.os.Bundle; import android.util.Log; import android.view.View; public class ViewDrawTestActivity extends Activity { // 用于测试 static int times = 1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MyView(this)); } /** * 内部类,继承View * * @author mark */ class MyView extends View { MyView(Context context) { super(context); } Paint vPaint = new Paint(); // 绘制样式物件 int i = 0; // 弧形角度 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Log.d("mark", "this run onDraw() " + (times++) + " times!"); // 设定绘图样式 vPaint.setColor(0xff00ffff); // 画笔颜色 vPaint.setAntiAlias(true); // 反锯齿 vPaint.setStyle(Paint.Style.STROKE); // 绘制一个弧形 canvas.drawArc(new RectF(60, 120, 260, 320), 0, i, true, vPaint); // 弧形角度 if ((i += 10) > 360) i = 0; // 重绘, 再一次执行onDraw 程序 //invalidate(); } } }运行效果:

可以看出,图像只画了一条线,说明onDraw()方法被调用一次。从log上也可以看出来:

D/mark ( 221): this run onDraw() 1 times!那么,是什么力量促使onDraw()方法被调用呢?

setContentView()View view方法,其实是调用PhoneWindow的setContentView(View view)方法,调用关系如下:


从而可以看出,invalidate()方法是促使onDraw()方法被调用的力量。
那么,修改代码,将内部类MyView的onDraw()方法中的invalidate()注释取消,再看看运行效果:



控制台:

D/mark ( 248): this run onDraw() 5629 times! D/mark ( 248): this run onDraw() 5630 times! D/mark ( 248): this run onDraw() 5631 times! D/mark ( 248): this run onDraw() 5632 times! D/mark ( 248): this run onDraw() 5633 times! D/mark ( 248): this run onDraw() 5634 times! D/mark ( 248): this run onDraw() 5635 times! D/mark ( 248): this run onDraw() 5636 times! D/mark ( 248): this run onDraw() 5637 times! D/mark ( 248): this run onDraw() 5638 times! D/mark ( 248): this run onDraw() 5639 times! D/mark ( 248): this run onDraw() 5640 times! D/mark ( 248): this run onDraw() 5641 times! D/mark ( 248): this run onDraw() 5642 times! D/mark ( 248): this run onDraw() 5643 times! D/mark ( 248): this run onDraw() 5644 times! D/mark ( 248): this run onDraw() 5645 times! D/mark ( 248): this run onDraw() 5646 times!可以看出,invalidate()方法使onDraw()一直被调用,实现重绘的效果。

在invalidate()方法源码中,有这么一段注释:

/** * Invalidate the whole view. If the view is visible, {@link #onDraw} will * be called at some point in the future. This must be called from a * UI thread. To call from a non-UI thread, call {@link #postInvalidate()}. */

这段话,说明了上面的实现(调用onDraw()方法)。但是在子线程中必须使用postInvalidate()方法。

如果有兴趣的话,请接着看View编程(3): invalidate()源码分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值