如何解決Android Canvas畫圖,不能動態展示在介面上的問題
阿新 • • 發佈:2019-02-13
最近用Canvas畫圖,發現畫圖的過程不能實時顯示在ImageView上,雖然嘗試了以下三種方法,仍然不行
按照google的一些建議添加了setWillNotDraw(false); 也不行
把畫圖過程寫在onDraw裡面,每隔一段時間imageView.invalidate(), 也不行。發現onDraw沒有被呼叫的到。
後來又更改程式碼使得onDraw隔一段時間被呼叫一次,但是每次onDraw呼叫,都是在一個新的傳進來的Canvas上畫圖,所以上次onDraw的影象是被清空的。而且onDraw只能通過訊息佇列觸發invalidate(),才能把onDraw的結果呈現在imageView上,手動呼叫onDraw,手動傳入Canvas,是不能正確呈現影象的。
那麼怎麼樣才能讓Canvas展現出動態的畫圖過程呢?重寫了一個ImageView類,在這個類裡面,用handler訊息機制去控制每隔一段時間呼叫一次onDraw,然後每次onDraw的時候把以前畫過得點重畫一遍,由於畫的速度非常快,視覺上呈現的效果就是動態的畫圖效果。
廢話不多說,程式碼如下,這裡想用三種顏色畫三種不同的小動物,所以有三個佇列儲存各個小動物的座標點。
package com.example.shirley.shirleysdemo.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Handler; import android.os.Message; import android.support.v7.widget.AppCompatImageView; import android.util.AttributeSet; import java.io.BufferedReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; /** * Created by shirley on 3/13/18. */ public class CanvasView extends AppCompatImageView { private Logger logger = Logger.getLogger(CanvasView.class.toString()); private Paint paint; public MyHandler myHandler; private List<MyPoint> pointListForWa = new ArrayList<>(); private List<MyPoint> pointListForNiu = new ArrayList<>(); private List<MyPoint> pointListForFly = new ArrayList<>(); public void setBufferedReaderForWa(BufferedReader bufferedReaderForWa) { this.bufferedReaderForWa = bufferedReaderForWa; } public void setBufferedReaderForNiu(BufferedReader bufferedReaderForNiu) { this.bufferedReaderForNiu = bufferedReaderForNiu; } public void setBufferedReaderForFly(BufferedReader bufferedReaderForFly) { this.bufferedReaderForFly = bufferedReaderForFly; } public void setCurrentBuffer(BufferedReader currentBuffer) { this.currentBuffer = currentBuffer; } private BufferedReader bufferedReaderForWa; private BufferedReader bufferedReaderForNiu; private BufferedReader bufferedReaderForFly; private BufferedReader currentBuffer = bufferedReaderForWa; private String readline = null; public CanvasView(Context context) { super(context); setWillNotDraw(false); myHandler = new MyHandler(this); initPaint(); } public CanvasView(Context context, AttributeSet attrs) { super(context, attrs); setWillNotDraw(false); myHandler = new MyHandler(this); initPaint(); } public CanvasView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setWillNotDraw(false); myHandler = new MyHandler(this); initPaint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawPoints(canvas); getNewPointByBundle(); } private void initPaint() { this.paint = new Paint(); paint.setColor(Color.rgb(13, 117, 6)); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth((float) 10.0); paint.setAntiAlias(true); paint.setAlpha(245); } private void setPaintColor(int red, int green, int black) { paint.setColor(Color.rgb(red, green, black)); } private void getNewPointByBundle() { int bundle = 20; for (int i = 0; i < bundle; i++) { getNewSinglePoint(); } } private void getNewSinglePoint() { if (paint != null && currentBuffer != null) { try { readline = currentBuffer.readLine(); if (readline != null) { if (readline.endsWith(".")) { String startAndEnd = readline.substring(0, readline.length() - 1); final String[] points = startAndEnd.split(","); if (points.length != 4) { logger.info("bad point!"); } else { Float startX = Float.valueOf(points[0]); Float startY = Float.valueOf(points[1]); Float endX = Float.valueOf(points[2]); Float endY = Float.valueOf(points[3]); MyPoint thispoint = new MyPoint(startX, startY, endX, endY); if (currentBuffer == bufferedReaderForWa) { pointListForWa.add(thispoint); } else if (currentBuffer == bufferedReaderForNiu) { pointListForNiu.add(thispoint); } else { pointListForFly.add(thispoint); } } } myHandler.sendEmptyMessageDelayed(1, 1); } else { if (currentBuffer == bufferedReaderForWa) { currentBuffer = bufferedReaderForNiu; myHandler.sendEmptyMessageDelayed(1, 1); } else if (currentBuffer == bufferedReaderForNiu) { currentBuffer = bufferedReaderForFly; myHandler.sendEmptyMessageDelayed(1, 1); } else { currentBuffer = null; } } } catch (IOException e) { e.printStackTrace(); } } } private void drawPoints(Canvas canvas) { if (paint != null) { setPaintColor(13, 117, 6); DrawPointWithList(canvas, pointListForWa); setPaintColor(234, 153, 153); DrawPointWithList(canvas, pointListForNiu); setPaintColor(204, 102, 255); DrawPointWithList(canvas, pointListForFly); } } private void DrawPointWithList(Canvas canvas, List<MyPoint> pointList) { for (MyPoint myPoint : pointList) { Float startX = myPoint.getStartX(); Float startY = myPoint.getStartY(); Float endX = myPoint.getEndX(); Float endY = myPoint.getEndY(); canvas.drawLine(startX, startY, endX, endY, paint); } } private class MyHandler extends Handler { private CanvasView canvasView; public MyHandler(CanvasView canvasView) { this.canvasView = canvasView; } @Override public void handleMessage(Message msg) { super.handleMessage(msg); canvasView.invalidate(); } } private class MyPoint { private Float startX; private Float startY; private Float endX; private Float endY; public MyPoint(Float startX, Float startY, Float endX, Float endY) { this.startX = startX; this.startY = startY; this.endX = endX; this.endY = endY; } public Float getStartX() { return startX; } public Float getStartY() { return startY; } public Float getEndX() { return endX; } public Float getEndY() { return endY; } } }