java 如何在 Android 中清除画布上的绘图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16377024/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 22:48:17  来源:igfitidea点击:

How to clear drawing on a canvas in Android

javaandroidandroid-canvas

提问by neknek mouh

I have already set up the canvas for the drawing. My problem now is how to clear the drawing.

我已经为绘图设置了画布。我现在的问题是如何清除绘图。

Tried doing this to no avail.

尝试这样做无济于事。

public void clear()
{
    circlePath.reset();
    mPath.reset();
    // Calls the onDraw() method
    //invalidate();
}

Please take a look at the whole code here:

请在此处查看整个代码:

https://gist.github.com/akosijiji/a29cca90bead2e5e35ad

https://gist.github.com/akosijiji/a29cca90bead2e5e35ad

Any help is truly appreciated.

任何帮助都非常感谢。

回答by Raghunandan

On button click

点击按钮

    b1.setOnClickListener(new OnClickListener()
    {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            dv.clear(); // call clear method using in your custom view


        }

    });

Define a clear method in your custom view

在您的自定义视图中定义一个 clear 方法

         public void clear()
        {
            mBitmap = Bitmap.createBitmap(width,height ,
                    Bitmap.Config.ARGB_8888);

        mCanvas = new Canvas(mBitmap);
        mPath = new Path();
            mBitmapPaint = new Paint(Paint.DITHER_FLAG);

            //Added later..
        mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setDither(true);
            mPaint.setColor(Color.GREEN);
            mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(12);
            invalidate();
        }

Reset all drawing tools and call invalidate to refresh the view.

重置所有绘图工具并调用 invalidate 以刷新视图。

Complete working code

完整的工作代码

public class MainActivity extends Activity implements ColorPickerDialog.OnColorChangedListener {

DrawingView dv ;
RelativeLayout rl;   
    private Paint       mPaint;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    dv = new DrawingView(this);
    setContentView(R.layout.activity_main);
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(Color.GREEN);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(12);
    rl = (RelativeLayout) findViewById(R.id.rl);
    rl.addView(dv);
    Button b = (Button) findViewById(R.id.button1);
    //b.setText(R.string.France);
    Button b1 = (Button) findViewById(R.id.button2);
    rl.setDrawingCacheEnabled(true);
    b.setOnClickListener(new OnClickListener()
    {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
              // dv.clear();    
             new ColorPickerDialog(MainActivity.this, MainActivity.this, mPaint.getColor()).show();


        }

    });

    b1.setOnClickListener(new OnClickListener()
    {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            dv.clear();


        }

    });

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

 public class DrawingView extends View {

        private int width;
        private  int height;
        private Bitmap  mBitmap;
        private Canvas  mCanvas;
        private Path    mPath;
        private Paint   mBitmapPaint;
        Context context;
        private Paint circlePaint;
        private Path circlePath;

        public DrawingView(Context c) {
        super(c);
        context=c;
        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);  
         circlePaint = new Paint();
         circlePath = new Path();
         circlePaint.setAntiAlias(true);
         circlePaint.setColor(Color.BLUE);
         circlePaint.setStyle(Paint.Style.STROKE);
         circlePaint.setStrokeJoin(Paint.Join.MITER);
         circlePaint.setStrokeWidth(4f); 


        }

        @Override
         protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width =w;
        height =h;
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);

        }
        public void clear()
        {
            mBitmap = Bitmap.createBitmap(width,height ,
                    Bitmap.Config.ARGB_8888);

                //Log.d("BITMAP","Restoring...");
                //mBitmap=BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 

            mCanvas = new Canvas(mBitmap);

            mPath = new Path();
            mBitmapPaint = new Paint(Paint.DITHER_FLAG);

            //Added later..
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setDither(true);
            mPaint.setColor(Color.GREEN);
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setStrokeJoin(Paint.Join.ROUND);
            mPaint.setStrokeCap(Paint.Cap.ROUND);
            mPaint.setStrokeWidth(12);
            invalidate();
        }
        @Override
        protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

        canvas.drawPath(mPath, mPaint);

        canvas.drawPath(circlePath, circlePaint);
        }

        private float mX, mY;
        private static final float TOUCH_TOLERANCE = 4;

        private void touch_start(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
        }
        private void touch_move(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
            mX = x;
            mY = y;

             circlePath.reset();
             circlePath.addCircle(mX, mY, 30, Path.Direction.CW); 
            // invalidate();

        }
        }
        private void touch_up() {
        mPath.lineTo(mX, mY);
        circlePath.reset();
        // commit the path to our offscreen
        mCanvas.drawPath(mPath, mPaint);
        // kill this so we don't double draw
        mPath.reset();
       // mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SCREEN));//.Mode.SCREEN));
        mPaint.setMaskFilter(null); 
        mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SCREEN); 

        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touch_start(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                touch_move(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                touch_up();
                invalidate();
                break;
        }
        return true;
        }  
        }
@Override
public void colorChanged(int color) {
    // TODO Auto-generated method stub
    mPaint.setColor(color);
} 
 }

The above works but it is not good design coz everytime you need to clear you will be creating objects like paint object.

以上工作,但它不是好的设计,因为每次你需要清除你将创建像油漆对象这样的对象。

You can create singleton class and have your tools reset and then call invalidate

您可以创建单例类并重置您的工具,然后调用 invalidate

 public class DrawingManager {

private static DrawingManager mInstance=null;

public DrawingTools mDrawingUtilities=null;

public int mThemeIndex;

    public Canvas  mCanvas;


    public Path    mPath;

    public Paint   mBitmapPaint;

    public Bitmap  mBitmap;

    public Paint  mPaint; 

private DrawingManager()
{

    resetDrawingTools();
}

public static DrawingManager getInstance()
{
    if(mInstance==null)
    {
        mInstance=new DrawingManager();         
    }

    return mInstance;
}


public void resetDrawingTools()
{

    mBitmap = Bitmap.createBitmap(screenwidth,screenheight ,
            Bitmap.Config.ARGB_8888)

    mCanvas = new Canvas(mBitmap);

    Path = new Path();
    mBitmapPaint = new Paint(Paint.DITHER_FLAG);

    //Added later..
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(Color.Green);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(12);


}

/**
 * Clears the drawing board.
 */
public static void clearDrawingBoard()
{
    mInstance=null;
}



public void resetBitmapCanvasAndPath() {
    // TODO Auto-generated method stub
    mBitmap = Bitmap.createBitmap(screenwidth,screenheight ,
            Bitmap.Config.ARGB_8888);

        //Log.d("BITMAP","Restoring...");
        //mBitmap=BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 

    mCanvas = new Canvas(.mBitmap);

    mPath = new Path();
}
}

In your painting class

在你的绘画课上

       private DrawingManager mDrawingManager=null;
       mDrawingManager=DrawingManager.getInstance();// initialize drawing tools once

Then on button click to clear draw

然后在按钮上单击以清除绘制

       mDrawingManager.resetBitmapCanvasAndPath();
       invalidate(); 

回答by itsrajesh4uguys

you should use yourpaintlayout.removeallviews();

你应该使用 yourpaintlayout.removeallviews();

you would have added one layout to your drawing canvas class. You will have option to remove all views from your drawing layout. hope this will help you.

您会在绘图画布类中添加一种布局。您可以选择从图纸布局中删除所有视图。希望这会帮助你。