Android中對View的更新有很多種方式,使用時要區分不同的應用場合。我感覺最要緊的是分清:多執行緒和雙緩衝的使用情況。

 

1.不使用多執行緒和雙緩衝

 

這種情況最簡單了,一般只是希望在View發生改變時對UI進行重繪。你只需在Activity中顯式地調用View物件中的invalidate()方法即可。系統會自動調用 View的onDraw()方法。

 

2.使用多執行緒和不使用雙緩衝

 

 
這種情況需要開啟新的執行緒,新開的執行緒就不好訪問View物件了。強行訪問的話會報:android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views.

 

這時候你需要創建一個繼承了android.os.Handler的子類,並重寫handleMessage(Message msg)方法。android.os.Handler是能發送和處理消息的,你需要在Activity中發出更新UI的消息,然後再你的Handler(可以使用匿名內部類)中處理消息(因為匿名內部類可以訪問父類變數, 你可以直接調用View物件中的invalidate()方法 )。也就是說:在新執行緒創建併發送一個Message,然後再主執行緒中捕獲、處理該消息。

 

3.使用多執行緒和雙緩衝

 

Android中SurfaceView是View的子類,她同時也實現了雙緩衝。你可以定義一個她的子類並實現SurfaceHolder.Callback介面。由於實現SurfaceHolder.Callback介面,新執行緒就不需要android.os.Handler幫忙了。SurfaceHolder中lockCanvas()方法可以鎖定畫布,繪製玩新的圖像後調用unlockCanvasAndPost(canvas)解鎖(顯示),還是比較方便得。

 

invalidate()函數重繪
public class PuzzleView extends View {
@Override
protected void onDraw(Canvas canvas) {
...
}

 

@Override
public boolean onTouchEvent(MotionEvent event) {
invalidate();
//處理邏輯
invalidate(); //刷
}
}
複製代碼
當調用執行緒處於空閒狀態時,會調用onDraw,刷新介面,也就是說,該函數僅是標記當前介面過期,並不直接負責刷新介面()
public class PuzzleView extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder surfaceHolder;

 

 
public PuzzleView(Context context){
//....
surfaceHolder = this.getHolder();//獲取holder
surfaceHolder.addCallback(this);
}

 

protected void paint(Canvas canvas) {
//這裡的代碼跟繼承View時OnDraw中一樣
}

 

public void repaint() {
Canvas c = null;
try {
c = surfaceHolder.lockCanvas();
paint(c);
} finally {
if (c != null) {
surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
 
 
FROM:http://www.devdiv.com/Android_view刷新-article-2100-1.html
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()