簡體   English   中英

Android SurfaceView,OnDraw被調用但顯示沒有更新而沒有invalidate()

[英]Android SurfaceView, OnDraw called but display is not updating without invalidate()

我在跟蹤典型的Android圖形流程時遇到了一些麻煩。 有很多例子,但我的似乎沒有用。 在我的主要活動中,我這樣做:

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

在我的資源文件中,我有3個覆蓋SurfaceView的自定義類。 在我對這些Surface Views的構造函數中,我有這樣的東西:

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

在我的線程運行方法中,我這樣做(從我見過的許多例子中解除):

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事件被調用,我的代碼應該正確更新圖形,但屏幕永遠不會更新。 我錯過了主要活動如何確定它需要重新繪制它的孩子的東西。

任何想法將不勝感激。 我花了一段時間試圖從一些工作演示中復制一些內容,但我似乎陷入困境。 謝謝

你在run()中所做的事情會做你做的任何事情 - 一次。 您需要重復繪圖過程。

一種方法是將所有內容放在while循環中

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

我已經遇到了同樣的問題。 由於我找不到任何解決方案,我做了一種解決方法:創建一個Bitmap作為緩沖區並繪制到該位圖。 繪制后,將完整的位圖繪制到視圖本身。 在View類中聲明這些變量:

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視圖invalidate ,具體取決於您是在同一線程還是在其他線程中調用該方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM