2012-09-07 94 views
3

我遇到了一個典型的Android圖形流量有點麻煩。有很多例子,但我似乎沒有工作。在我的主要活動中,我這樣做:Android SurfaceView,OnDraw調用但顯示不更新沒有invalidate()

super.onCreate(savedInstanceState);       
setContentView(R.layout.activity_main); 

在我的資源文件中,我有3個覆蓋SurfaceView的自定義類。在我的構造函數,這些表面查看我有這樣的事情:

super(context, attrs); 
getHolder().addCallback(this); 
this.thread = new MyThread(getHolder(),this); 

在我的線程的run方法我這樣做(從很多例子舉起我見過):

Canvas c; 
try { 
    c = surfaceHolder.lockCanvas(null); 
    synchronized (surfaceHolder) { 
     panel.onDraw(c); 
    } 
} finally { 
    if (c != null) { 
    surfaceHolder.unlockCanvasAndPost(c); 
} 

該線程啓動在我的SurfaceView的'surfaceCreated'事件中。在onDraw有我這樣做:

public void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    <some drawing stuff here using canvas> 
} 

當我運行,線程確實跑了,我可以看到的onDraw獲取調用(我擺在那裏登錄打印命令),但我的圖形不作爲更新預期。如果我叫this.invalidate(),但是,圖形做更新的時間屈指可數,因爲我希望等到我這個崩潰:

E/AndroidRuntime(748): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 

根據我看到我不應該需要的例子我意識到在OnDraw中調用invalidate,但我只是爲了驗證我的onDraw中的代碼是否有效。所以,在我看來,如果沒有invalidate(),onDraw事件就會被調用,並且我的代碼應該正確更新圖形,但屏幕永遠不會更新。我錯過了主要活動實際決定它需要重新繪製它的孩子的事情。

任何想法將不勝感激。我花了一段時間試圖從一些工作演示中複製內容,但我似乎被卡住了。謝謝

+0

請記住,SurfaceViews有兩部分:表面部分和視圖部分。後者是UI視圖層次結構的一部分,並且只能從UI線程(通過onDraw())繪製,但只有在View系統認爲有工作要做(例如在無效之後)時纔會被調用。前者是一個完全獨立的層,可以隨時從任意線程更新。你的意思是要同時使用這兩種方法嗎? – fadden

回答

0

你在run()中做的事情會做你所做的一切 - 一次。 您需要重複繪製過程。

的一種方法是把一切while循環

while(true){ 
    try { 
     c = surfaceHolder.lockCanvas(null); 
     synchronized (surfaceHolder) { 
      panel.onDraw(c); 
     } 
    } finally { 
     if (c != null) { 
     surfaceHolder.unlockCanvasAndPost(c); 
    } 
} 
+0

我很抱歉,我的小程式碼片段並不完整。我有一個while循環,我可以看到線程正在循環中運行。我試圖刪除一些與手頭問題沒有關係的代碼,但我應該把它留下。無論如何,謝謝。 –

0

我已經有同樣的問題裏面。由於我找不到任何解決方案,我採取了一種解決方法:創建一個Bitmap作爲緩衝區並繪製到該位圖。繪製完成後,將完整的位圖繪製到視圖本身。在您的視圖類聲明這些變量:

Canvas bmpCanvas; 
Bitmap bmp; 

而在你的onDraw()使用它 - 法像圖所示:

@Override 
protected void onDraw(Canvas canvas) { 

    if(bmp == null || bmpCanvas == null) { 

     bmp = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); 
     bmpCanvas = new Canvas(bmp); 
    } 

    //do drawing-stuff here 

    canvas.drawBitmap(bmp, 0, 0, p); //where p is a Paint-Object. 
} 

現在,更新視圖/調用此方法兼用invalidatepostInvalidate()invalidate您的看法,取決於您是否在同一個線程或其他線程中調用該方法。

相關問題