根据按下的按钮拖动并绘制矩形和圆形?

时间:2016-03-22 12:26:02

标签: android android-canvas android-view

所以我试图制作一个应用程序,通过为每个形状,圆形和矩形选择相应的按钮,可以在同一个画布上拖动和绘制两个不同的形状。我有一个自定义视图,在我的布局中称为绘图视图和两个按钮。每个按钮的on click侦听器将一个字符串放在共享首选项中,指示所选的形状。然后视图在用户拖动手指时在画布上绘制相应的形状。这是我的观点类:

public class DrawingView extends View {
    private Box mCurrentBox;
    private List<Box> mBoxen = new ArrayList<>();
    private Paint mBoxPaint;

    private Circle mCurrentCircle;
    private List<Circle> mCirclen = new ArrayList<>();
    private Paint mCirclePaint;

    private Paint mBackgroundPaint;

    // Used when creating the view in code
    public DrawingView(Context context) {
        this(context, null);
    }

    // Used when inflating the view from XML
    public DrawingView(Context context, AttributeSet attrs) {
        super(context, attrs);

        // Paint the boxes a nice semitransparent red (ARGB)
        mBoxPaint = new Paint();
        mBoxPaint.setColor(0x22ff0000);

        mCirclePaint = new Paint();
        mCirclePaint.setColor(0x22ff0000);

        // Paint the background off-white
        mBackgroundPaint = new Paint();
        mBackgroundPaint.setColor(0xfff8efe0);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        // Fill the background
        canvas.drawPaint(mBackgroundPaint);

        if (PreferencesHelper.getStoredShape(getContext()) == "box") {

            for (Box box : mBoxen) {
                float left = Math.min(box.getOrigin().x, box.getCurrent().x);
                float right = Math.max(box.getOrigin().x, box.getCurrent().x);
                float top = Math.min(box.getOrigin().y, box.getCurrent().y);
                float bottom = Math.max(box.getOrigin().y, box.getCurrent().y);

                canvas.drawRect(left, top, right, bottom, mBoxPaint);
            }
        }

        else if(PreferencesHelper.getStoredShape(getContext()) == "circle") {

            for (Circle circle : mCirclen) {
                float left = Math.min(circle.getOrigin().x, circle.getCurrent().x);
                float right = Math.max(circle.getOrigin().x, circle.getCurrent().x);
                float top = Math.min(circle.getOrigin().y, circle.getCurrent().y);
                float bottom = Math.max(circle.getOrigin().y, circle.getCurrent().y);

                float cx = circle.getOrigin().x;
                float cy = circle.getOrigin().y;

                float radius = (float) Math.sqrt((right - left) * (right - left) + (bottom - top) * (bottom - top));

                canvas.drawCircle(cx, cy, radius, mCirclePaint);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        PointF current = new PointF(event.getX(), event.getY());
        String action = "";


        if (PreferencesHelper.getStoredShape(getContext()) == "box") {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    action = "ACTION_DOWN";
                    // Reset drawing state
                    mCurrentBox = new Box(current);
                    mBoxen.add(mCurrentBox);
                    break;
                case MotionEvent.ACTION_MOVE:
                    action = "ACTION_MOVE";
                    if (mCurrentBox != null) {
                        mCurrentBox.setCurrent(current);
                        invalidate();
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    action = "ACTION_UP";
                    mCurrentBox = null;
                    break;
                case MotionEvent.ACTION_CANCEL:
                    action = "ACTION_CANCEL";
                    mCurrentBox = null;
                    break;
            }
        }
        else if (PreferencesHelper.getStoredShape(getContext()) == "circle") {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        action = "ACTION_DOWN";
                        // Reset drawing state
                        mCurrentCircle = new Circle(current);
                        mCirclen.add(mCurrentCircle);
                        break;
                    case MotionEvent.ACTION_MOVE:
                        action = "ACTION_MOVE";
                        if (mCurrentCircle != null) {
                            mCurrentCircle.setCurrent(current);
                            invalidate();
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        action = "ACTION_UP";
                        mCurrentCircle = null;
                        break;
                    case MotionEvent.ACTION_CANCEL:
                        action = "ACTION_CANCEL";
                        mCurrentCircle = null;
                        break;
                }
        }
        return true;
    }
} 

绘制两个形状的功能很好但问题是应用程序似乎有两个不同的画布来绘制两个不同的形状。例如,当选择矩形时,您可以拖动并绘制无尽的矩形,但是当您切换到圆形时,它会切换到黑色画布并让您拖动并绘制无尽的圆形。当您切换回矩形时,它会保留画布上绘制矩形的内容,并在切换回圆形时保存相同的内容。

我希望能够在画布上绘制尽可能多的矩形,然后切换到已经绘制的矩形顶部的绘图圆圈。是什么导致这种情况发生?

1 个答案:

答案 0 :(得分:0)

首先,我认为你的形状可能会更好。您可以使用Shape方法创建draw界面,将形状绘制到画布,然后让BoxCircle类实现Shape。通过这种方式,您可以拥有一个List<Shape>,从而简化您的逻辑。

public interface Shape {

    void setOrigin(float x, float y);

    void setTerminal(float x, float y);

    void draw(Canvas canvas);
}
public class Box implements Shape {

    private PointF mOrigin;
    private PointF mTerminal;

    private Paint mPaint;

    public Box(Paint paint) {
        mPaint = paint;
    }

    public void setOrigin(float x, float y) {
        mOrigin = new PointF(x, y);
    }

    public void setTerminal(float x, float y) {
        mTerminal = new PointF(x, y);
    }

    public void draw(Canvas canvas) {
        float left = Math.min(mOrigin.x, mTerminal.x);
        float right = Math.max(mOrigin.x, mTerminal.x);
        float top = Math.min(mOrigin.y, mTerminal.y);
        float bottom = Math.max(mOrigin.y, mTerminal.y);

        canvas.drawRect(left, top, right, bottom, mPaint);
    }
}

然后在onDraw中,您可以调用Shape中所有List个对象的绘制方法:

private Shape mCurrentShape;
private List<? extends Shape> mShapes;

...

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

    for(Shape shape : mShapes) {
        shape.draw(canvas);
    }

    mCurrentShape.draw(canvas);
}

我认为这可能会简化您的一些逻辑,并使您能够在单个画布上绘制多个形状。但是,正如我在评论中所说,我不知道这是否能解决你所获得的黑色背景。