Android之view重绘

http://qaohao.javaeye.com/blog/478314

 

关键字: android android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。
以下是我在android文档中找到的说明,

引用
public void invalidate()
Invalidate the whole view. If the view is visible, onDraw(Canvas) 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 postInvalidate().

public void postInvalidate ()
Cause an invalidate to happen on a subsequent cycle through the event loop. Use this to invalidate the View from a non-UI thread.


google的文档的说明实在是简单,往往看了开发中都会遇到这两个问题:
1. 没有任何异常,view没能刷新。
2. android应用异常终止,打开logcat会看到这样的异常信息, Only the original thread that created a view hierarchy can touch its views。

最后,通过查文档,上网查询才知道,invalidate和postInvalidate方法需要使用android提供的handler,才能 实现重绘,而在文档的说明中却只字不提,真是简单啊。具体是在需要重绘的地方调用handler的sendMessage方法发送消息,紧接着会os会触 发handler中的handlerMessage方法,在handlerMessage方法中再调用view的invalidate或者 postInvalidate方法就能实现重绘。

下面是我分别针对invalidate方法,给出view重绘代码,仅供参考:

Java代码
  1. class  CustomizeView  extends  WhichView {  
  2.   
  3.     public  CustomizeView(Context context) {  
  4.         super (context);  
  5.         final  Handler handler =  new  Handler();  
  6.   
  7.         new  Thread( new  Runnable() {  
  8.             @Override   
  9.             public   void  run() {  
  10.                 // delay some minutes you desire.   
  11.                 /*try {  
  12.                     Thread.sleep(3000);  
  13.                 } catch (InterruptedException e) {  
  14.                 }*/   
  15.                 handler.post(new  Runnable() {  
  16.                     public   void  run() {  
  17.                         concreteUpdateUI();  
  18.                         invalidate();  
  19.                     }  
  20.                 });  
  21.             }  
  22.         }).start();  
  23.     }  
  24.   
  25.     protected   void  concreteUpdateUI() {  
  26.         // Add concrete movement for UI updates.   
  27.         // ...   
  28.     }  
  29. }  
class CustomizeView extends WhichView {public CustomizeView(Context context) {super(context);final Handler handler = new Handler();new Thread(new Runnable() {@Overridepublic void run() {// delay some minutes you desire./*try {Thread.sleep(3000);} catch (InterruptedException e) {}*/handler.post(new Runnable() {public void run() {concreteUpdateUI();invalidate();}});}}).start();}protected void concreteUpdateUI() {// Add concrete movement for UI updates.// ...}}


或者这样实现也可以。

Java代码
  1. class  CustomizeView  extends  TextView {  
  2.   
  3.     public  CustomizeView(Context context) {  
  4.         super (context);  
  5.         new  Thread( new  UIUpdateThread()).start();  
  6.     }  
  7.   
  8.     class  UIUpdateThread  implements  Runnable {  
  9.         final  Handler mHandler =  new  Handler();  
  10.   
  11.         final  Runnable mUpdateResults =  new  Runnable() {  
  12.             public   void  run() {  
  13.                 concreteUpdateUI();  
  14.                 invalidate();  
  15.             }  
  16.         };  
  17.   
  18.         public   void  run() {  
  19.             // delay some minutes you desire.    
  20.             /*try {  
  21.                 Thread.sleep(1000 * 5);  
  22.             } catch (InterruptedException e) {  
  23.                 e.printStackTrace();  
  24.             }*/   
  25.             mHandler.post(mUpdateResults);  
  26.         }  
  27.   
  28.     }  
  29.   
  30.     protected   void  concreteUpdateUI() {  
  31.         // Add concrete movement for UI updates.     
  32.         // ...     
  33.     }  
  34.   

我上面提供的代码,只是一个架子,这个架子里面只能实现两种情形:
1)其一就是android控件延时刷新,修改方法就是在UIUpdateThread类的run方法在呼出Handler的post方法之前增加一个延迟。
try {
         Thread.sleep(1000 * 5);
  } catch (InterruptedException e) {
         e.printStackTrace();
  }
    举个例子说明一下它在什么场合应用吧,比如启动游戏前的动画,是不是Imageview就可以通过这个延时刷新来实现启动动画的效果,刚开始加载一幅画,过会换一幅画。

2)其二就是android控件定时刷新,那就得在修改CustomizeView构造方法,将UIUpdateThread添加到Timer中,这样就可以实现定时刷新。


那么如果你需要不定时刷新的话,那我提供的这个架子就不适用了,你得自己去调用Handler的post方法。这种情况应该是最常见的。
class CustomizeView extends TextView {public CustomizeView(Context context) {super(context);new Thread(new UIUpdateThread()).start();}class UIUpdateThread implements Runnable {final Handler mHandler = new Handler();final Runnable mUpdateResults = new Runnable() {public void run() {concreteUpdateUI();invalidate();}};public void run() {// delay some minutes you desire. /*try {Thread.sleep(1000 * 5);} catch (InterruptedException e) {e.printStackTrace();}*/mHandler.post(mUpdateResults);}}protected void concreteUpdateUI() {// Add concrete movement for UI updates.  // ...  }}

更多相关文章

  1. 浅谈Java中Collections.sort对List排序的两种方法
  2. Python list sort方法的具体使用
  3. python list.sort()根据多个关键字排序的方法实现
  4. Android(安卓)Service生命周期及用法!
  5. Android(安卓)home键和back键区别
  6. SharePreferences实现
  7. [转]JS调用Android里面的方法,Android调用JS里面的方法
  8. android UI进阶之弹窗的使用(2)--实现通讯录的弹窗效果
  9. Android判断ListView滚动到最顶部第0条item完全完整可见及最底部

随机推荐

  1. Android 开发网站网址
  2. Android:CountDownTimer 实现倒计时功能
  3. Android的Audio系统详解
  4. Android 6.0 去掉锁屏
  5. Android小项目之底部导航(RadioButton&Fr
  6. Android Relativelayout布局属性
  7. 【Android 应用开发】 Android APK 反编
  8. Android 手势滑动,多点触摸放大缩小图片
  9. Android 禁止转屏的方法
  10. PackageManagerService的启动过程分析