1. 程式人生 > >如何解決Android Canvas畫圖,不能動態展示在介面上的問題

如何解決Android Canvas畫圖,不能動態展示在介面上的問題

最近用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;
        }

    }

}