[英]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.
}
現在,要更新視圖/調用此方法,請使用invalidate
或postInvalidate()
invalidate
視圖invalidate
,具體取決於您是在同一線程還是在其他線程中調用該方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.