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

来源:互联网 发布:网络黄金未来城网址 编辑:程序博客网 时间:2024/06/05 19:00


转自:http://blog.csdn.net/veryitman/article/details/6692950

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


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


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

[java] view plaincopyprint?
  1. package mark.zhang;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Context;  
  5. import android.graphics.Canvas;  
  6. import android.graphics.Paint;  
  7. import android.graphics.RectF;  
  8. import android.os.Bundle;  
  9. import android.util.Log;  
  10. import android.view.View;  
  11.   
  12. public class ViewDrawTestActivity extends Activity {  
  13.     // 用于测试  
  14.     static int times = 1;  
  15.   
  16.     @Override  
  17.     public void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(new MyView(this));  
  20.     }  
  21.       
  22.     /** 
  23.      * 内部类,继承View 
  24.      *  
  25.      * @author mark 
  26.      */  
  27.     class MyView extends View {  
  28.   
  29.         MyView(Context context) {  
  30.             super(context);  
  31.         }  
  32.         Paint vPaint = new Paint(); // 绘制样式物件  
  33.         int i = 0// 弧形角度  
  34.         @Override  
  35.         protected void onDraw(Canvas canvas) {  
  36.             super.onDraw(canvas);  
  37.             Log.d("mark""this run onDraw() " + (times++) + " times!");  
  38.             // 设定绘图样式  
  39.             vPaint.setColor(0xff00ffff); // 画笔颜色  
  40.             vPaint.setAntiAlias(true); // 反锯齿  
  41.             vPaint.setStyle(Paint.Style.STROKE);  
  42.             // 绘制一个弧形  
  43.             canvas.drawArc(new RectF(60120260320), 0, i, true, vPaint);  
  44.             // 弧形角度  
  45.             if ((i += 10) > 360)  
  46.                 i = 0;  
  47.             // 重绘, 再一次执行onDraw 程序  
  48.             //invalidate();  
  49.         }  
  50.     }  
  51. }  
运行效果:

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

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

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


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



控制台:

[html] view plaincopyprint?
  1. D/mark    (  248): this run onDraw() 5629 times!  
  2. D/mark    (  248): this run onDraw() 5630 times!  
  3. D/mark    (  248): this run onDraw() 5631 times!  
  4. D/mark    (  248): this run onDraw() 5632 times!  
  5. D/mark    (  248): this run onDraw() 5633 times!  
  6. D/mark    (  248): this run onDraw() 5634 times!  
  7. D/mark    (  248): this run onDraw() 5635 times!  
  8. D/mark    (  248): this run onDraw() 5636 times!  
  9. D/mark    (  248): this run onDraw() 5637 times!  
  10. D/mark    (  248): this run onDraw() 5638 times!  
  11. D/mark    (  248): this run onDraw() 5639 times!  
  12. D/mark    (  248): this run onDraw() 5640 times!  
  13. D/mark    (  248): this run onDraw() 5641 times!  
  14. D/mark    (  248): this run onDraw() 5642 times!  
  15. D/mark    (  248): this run onDraw() 5643 times!  
  16. D/mark    (  248): this run onDraw() 5644 times!  
  17. D/mark    (  248): this run onDraw() 5645 times!  
  18. D/mark    (  248): this run onDraw() 5646 times!  
可以看出,invalidate()方法使onDraw()一直被调用,实现重绘的效果。

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

[html] view plaincopyprint?
  1. /**  
  2.     * Invalidate the whole view. If the view is visible, {@link #onDraw} will  
  3.     * be called at some point in the future. This must be called from a  
  4.     * UI thread. To call from a non-UI thread, call {@link #postInvalidate()}.  
  5.     */  

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


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



0 0
原创粉丝点击