多次绘制 Canvas

Draw on Canvas multiple times

我在 class 的练习中遇到了一个小问题。练习是在 Canvas 上多次绘制形状。但是我只能画一次,当我画另一个时,之前的被删除了。这是我的 CustomView 代码。 figuras 是一个形状的 LinkedList,将来我会保存它们。在抽奖时,我将从 LinkedList 中抽取数字。

包 com.example.AndroidTest;

    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Paint.Style;
    import android.text.TextUtils;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.Toast;

    import java.util.LinkedList;

public class 自定义视图扩展视图 {

private final Paint brush;
private LinkedList<Figures> figuras;
public int id;
private float startX;
private float endX;
private float startY;
private float endY;
Figures fig; // á partida é para mudar para o createFigure
public CustomView(Context context, LinkedList <Figures> figures)
{
    super(context);
    brush = new Paint();
    brush.setStyle(Style.STROKE);
    brush.setColor(Color.WHITE);
    brush.setStrokeWidth(6);
    figuras = figures;
}

@Override
protected void onDraw(Canvas canvas)
{
    super.onDraw(canvas);


        createFigure( startX,  startY,  endX,  endY);
        fig.drawFigure(canvas, brush);
        invalidate();

}

public String getString(){
    String joined = TextUtils.join("\n\n", figuras); return joined;
} // criar uma string a copiar o conteudo duma list com o intervalo de uma virgula.


@Override
public boolean onTouchEvent( MotionEvent event) {

    if (event.getAction() == event.ACTION_DOWN) {
        startY = event.getY();
        startX = event.getX();
        endY = event.getY();
        endX = event.getX();
        figuras.add(fig);
        Toast.makeText(getContext(), "" + figuras.size(), Toast.LENGTH_SHORT).show();

    } else if (event.getAction() == event.ACTION_MOVE) {
        endY = event.getY();
        endX = event.getX();
        figuras.getLast().setEndVars(endX, endY);

    }
    return super.onTouchEvent(event);
}

public void createFigure(float startX, float startY, float endX, float endY) {


    switch (id) // aqui crio a figura Fig fig = new line/circle/rect
    {
        case 0:
            fig = new Line(startX, startY, endX, endY);
            break;
        case 1:
            fig = new Circle(startX, startY, endX, endY);
            break;
        case 2:
            fig = new Rectangle(startX, startY, endX, endY);
            break;
    }
    //return fig;
}

public void setID(int aux)
{
    id = aux;
}

public LinkedList<Figures> getArray()
{
    return figuras;
}

}

调用invalidate后,所有已绘制的内容都将被擦除并再次调用onDraw。目前您正在无限循环中绘图,每次使用 startY、startX、endY 和 endX 变量的当前值绘制一个图形,然后使您绘制的内容无效。如果这些变量发生了变化,则不会再绘制旧图形。

为了绘制新图形和所有旧图形,每次调用 onDraw 时,您都必须迭代 figuras 并再次绘制每个图形。然后你应该看到所有添加到 figuras 的数字,因此你想要绘制的所有数字。像这样:

protected void onDraw(Canvas canvas)
{
   super.onDraw(canvas);
   for(Figures f : figuras) {
      f.drawFigure(canvas, brush);
   }
}

另外两个关于性能的概念。您应该在 onTouchEvent 中而不是在 onDraw 中调用 invalidate。那将节省大量的计算能力。目前我敢打赌,您可以将 phone 用作暖手器。 您还应该在 onTouchEvent 中创建图形。在 onDraw 中只做必要的事情。其他一切都应该在 onDraw.

之外