如何随时在视图上绘制形状和线条?

时间:2015-09-26 01:30:19

标签: java android canvas draw

通过“每当我想要”时,我的意思是当用户点击按钮或发生某种事件或onCreate时,我可以在其上绘制新内容......我找到了一些教程,他们说我应该创建自定义视图并覆盖onDraw。所以我尝试了以下内容:

public class CanvasView extends View {
    private Canvas canvas;
    private Paint paint;

    public Canvas getCanvas() {
        return canvas;
    }

    public Paint getPaint () {
        return paint;
    }

    public CanvasView (Context c) {
        super(c);
        paint = new Paint ();
        paint.setColor (Color.BLACK);
        paint.setStrokeWidth (5);
    }

    public CanvasView(Context context, AttributeSet attrs) {
        super (context, attrs);
        paint = new Paint ();
        paint.setColor (Color.BLACK);
        paint.setStrokeWidth (5);
    }

    public CanvasView(Context context, AttributeSet attrs, int defStyleAttr) {
        super (context, attrs, defStyleAttr);
        paint = new Paint ();
        paint.setColor (Color.BLACK);
        paint.setStrokeWidth (5);
    }

    @Override
    protected void onDraw (Canvas c) {
        canvas = c;
    }
}

也许我太天真了。我添加了一个名为canvas的字段并添加了一个getter。如您所见,在onDraw方法中,我将canvas参数分配给字段。然后在onCreate方法中我做了这个:

canvas = (CanvasView)findViewById (R.id.canvas);
canvas.getCanvas ().drawLine (100, 100, 500, 100, canvas.getPaint ());

我认为我所做的真的很傻。无论如何,我运行我的应用程序...... NPE!我推断canvas.getCanvas()为空。

所以这个方法不起作用。我的代码出了什么问题?如果我不这样做,我可以使用哪些其他视图来随时随地绘制内容?

2 个答案:

答案 0 :(得分:0)

您写道:

  

然后在onCreate方法中我这样做了:   canvas =(CanvasView)findViewById(R.id.canvas);   canvas.getCanvas().drawLine(100,100,500,100,canvas.getPaint());

  1. 您需要在onDraw(...)中进行绘图。将canvas.drawline(...)移至该方法。

  2. canvas.drawLine(...)代替canvas.getCanvas().drawLine(...)

  3. 您需要初始化Paint实例。不要canvas.getPaint()。创建一个字段mPaint并在构造函数中初始化它。

  4. 有关完整的工作示例,请参阅Android开发人员,自定义绘图: http://developer.android.com/training/custom-views/custom-drawing.html

答案 1 :(得分:0)

我想到了一个解决方案,它的工作原理!我删除了自定义视图中的Canvas字段以及Paint字段。然后我创建了一个名为Shape的接口:

public interface Shape {
    void draw (Canvas c);
}

这是新的CanvasView类:

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;

import java.util.ArrayList;

public class CanvasView extends View {
    private ArrayList<Shape> shapes;

    public CanvasView (Context c) {
        super(c);
        init ();
    }

    public CanvasView(Context context, AttributeSet attrs) {
        super (context, attrs);
        init ();
    }

    public CanvasView(Context context, AttributeSet attrs, int defStyleAttr) {
        super (context, attrs, defStyleAttr);
        init ();
    }

    private void init () {
        shapes = new ArrayList<> ();
    }

    @Override
    protected void onDraw (Canvas c) {
        super.onDraw (c);
        for (Shape s : shapes) {
            s.draw (c);
        }
    }

    public void addShape (Shape s) {
        shapes.add (s);
    }

    public void clear () {
        shapes.clear ();
    }
}

如您所见,该类具有需要绘制的形状的数组列表。我们可以像这样实现draw方法来画一条线:

    canvas.addShape (new Shape () {
        @Override
        public void draw(Canvas c) {
            Paint p = new Paint ();
            p.setColor (Color.BLACK);
            p.setStrokeWidth (5);
            c.drawLine (100, 100, 500, 100, p);
        }
    });

我认为这是一个很好的方法。它基本上使用接口作为&#34;委托&#34;在画布上绘制一个形状。调用onDraw后,它会在ArrayList上的Canvas中绘制所有形状。哦,参考类型的美丽!