在画布中绘制和擦除圆圈

问题描述 投票:1回答:1

我是Android的新手,所以我不知道这个问题是否是基本的。

我想每N秒画一次画布。

寻找教程,我成功地将一个圆圈画成了画布。但随后出现了问题。如何擦除我之前绘制的圆圈。

我这样做的方式可能很糟糕,事实上,我只画了另一个圆圈(但是白色)。这意味着,每次迭代我画一个白色圆圈以擦除前一个。然后是蓝色的新圆圈。

它完全适用于第一次迭代......但是一旦我开始在我已经绘制圆圈的地方绘制圆形......事情开始出错...就像再次绘制一些先前擦除的圆圈一样又出现了。

我真的不知道如何解释它。

您可以看到执行此代码安静的情况。

我的游戏活动发射器

public class GameActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Float max = new Float(200.42);
        ArrayList<Float> liste_test = new ArrayList<Float>();
        liste_test.add(new Float(36.8));
        liste_test.add(new Float(147.8));
        liste_test.add(new Float(97.8));
        liste_test.add(new Float(max));
        liste_test.add(new Float(10));
        setContentView(new ExampleSurfaceView(this,liste_test,max));
    }
}

我的ExampleSurfaceView我用来从列表中使用'normalized'数据绘制圆圈。

public class ExampleSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
    // Le holder
    SurfaceHolder mSurfaceHolder;
    // Le thread dans lequel le dessin se fera
    DrawingThread mThread;

    int oldPosition_x;
    int oldPosition_y;

    ArrayList<Integer> valeurs_capteurs;
    int nb_valeurs;

    public ExampleSurfaceView (Context context,ArrayList<Float> donees_capteur, Float max) {
        super(context);
        this.valeurs_capteurs=normalise(donees_capteur,max);
        this.nb_valeurs=this.valeurs_capteurs.size();
        mSurfaceHolder = getHolder();
        mSurfaceHolder.addCallback(this);

        mThread = new DrawingThread();
    }

    //pour récupérer des données uniforme peu importe le capteur
    public ArrayList<Integer> normalise(ArrayList<Float> donnees, Float max){
        valeurs_capteurs = new ArrayList<Integer>();
        for (Float donnee : donnees) {
            int donnee_normalized= (int)((donnee/max)*100);
            valeurs_capteurs.add(donnee_normalized);
        }
        return valeurs_capteurs;
    }


    protected void onDraw(Canvas canvas,int nb) {
        //dessinez ici
        super.onDraw(canvas);
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);

        int index = nb%(nb_valeurs-1);

        System.out.println(index);

        //On calcule une position à partir des données du capteur
        int circlePositionX = 60+this.valeurs_capteurs.get(index);
        int circlePositionY = 60+this.valeurs_capteurs.get(index);


        //initialisation au premier draw
        if(nb==0){
            oldPosition_x=circlePositionX;
            oldPosition_y=circlePositionY;
        }

        //effacer l'andien cercle
        paint.setColor(Color.WHITE);
        canvas.drawCircle(oldPosition_x,oldPosition_y, 50,paint);
        System.out.println("Erase in "+oldPosition_x+" - "+oldPosition_y);

        oldPosition_x=circlePositionX;
        oldPosition_y=circlePositionY;

        //dessiner le nouveau cercle
        paint.setColor(Color.BLUE);
        canvas.drawCircle(circlePositionX, circlePositionY, 50,paint);
        System.out.println("Draw in "+circlePositionX+" - "+circlePositionY);

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        // Que faire quand le surface change ? (L'utilisateur tourne son téléphone par exemple)
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mThread.keepDrawing = true;
        mThread.start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mThread.keepDrawing = false;

        boolean joined = false;
        while (!joined) {
            try {
                mThread.join();
                joined = true;
            } catch (InterruptedException e) {}
        }
    }

    private class DrawingThread extends Thread {
        // Utilisé pour arrêter le dessin quand il le faut
        boolean keepDrawing = true;

        @SuppressLint("WrongCall")
        @Override
        public void run() {

            int nb=0;
            while (keepDrawing) {
                Canvas canvas = null;

                try {
                    // On récupère le canvas pour dessiner dessus
                    canvas = mSurfaceHolder.lockCanvas();
                    // On s'assure qu'aucun autre thread n'accède au holder
                    synchronized (mSurfaceHolder) {
                        // Et on dessine
                        onDraw(canvas,nb);
                        nb+=1;
                    }
                } finally {
                    // Notre dessin fini, on relâche le Canvas pour que le dessin s'affiche
                    if (canvas != null)
                        mSurfaceHolder.unlockCanvasAndPost(canvas);
                }

                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {}
            }
        }
    }
}

当我在看印刷品时,数据似乎是逻辑,我擦除并打印到好地方......但问题仍然存在......显然我做错了什么,但我无法弄清楚是什么它经过多次搜索。谢谢你的协助。

java android android-canvas
1个回答
1
投票

如果您要删除画布上的所有内容,可以在onDraw方法的开头调用它:

canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)

此外,为了每秒绘制画布60次,您可以在invalidate()函数的末尾调用onDraw。您可能不需要表面,只需使用自定义View而不是SurfaceView,这样每次调用onDraw时它都会自动清除

© www.soinside.com 2019 - 2024. All rights reserved.