Blog

  • First we will create application for drawing on canvas.

    Canvas class is used in 2D drawing holds the "draw" calls.To draw anything we need four primitive.

    1)Bitmap to hold the pixels on which will take operations on it.

    2) Canvas to write into bitmap which hosts the draw calls.

    3)Paint  will be used to describe colours and style used for drawing.

    4)Drawing primitive basically (Rect,Path) called handy tools.

     

     

    Now we will create CanvasPencilView which extends View.So View class has some methods which help in drawing on canvas.Some of those method we will use in this.

     

     

    Next we will initialize all primitive as class variable.Like this

     

     

    private Path drawPath;
        private Paint drawPaint,canvasPaint;
        private Bitmap canvasBitmap;
        private Canvas drawCanvas;
    

     

     

    Next  we will use constructor of class and assign values to all primitives. Code snippet will be like this.

     

     

    public CanvasPencilView(Context context, AttributeSet attributeSet) {
            super(context, attributeSet);
            setUpDrawing();
        }
    
        private void setUpDrawing() {
            drawPath = new Path();
            drawPaint = new Paint();
            drawPaint.setColor(Color.parseColor("#ff0000"));
            drawPaint.setAntiAlias(true);
            drawPaint.setStrokeWidth(20);
            drawPaint.setStyle(Paint.Style.STROKE);
            //drawPaint.setStrokeJoin(Paint.Join.ROUND);
            drawPaint.setStrokeCap(Paint.Cap.ROUND);
            canvasPaint = new Paint(Paint.DITHER_FLAG);
        }
    

     

     

    Next we will assign a bitmap to canvas on which drawing will be done using view method. Code snippet will be 

     

     

     @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            canvasBitmap=Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);
            drawCanvas=new Canvas(canvasBitmap);
        }
    

     

     

    Next there will be onDraw() method which will be used to draw on canvas.Code snippet will be

     

     

    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawBitmap(canvasBitmap,0,0,canvasPaint);
            canvas.drawPath(drawPath,drawPaint);
        }
    

     

     

    Next there will be method onTouchEvent(MotionEvent event) which will handle all touch events occuured on canvas using MotionEvent.

    Some MotionEvents are:

     

     

    Action_Down:This events is invoked when screen is touched

    Action_Move:This events is invoked when someone touch and starts dragging on screen.

    Action_Up:This events is invoked when someone removes fingers from screen.

     

     

    Code Snippet will be like:

     

     

    @Override
        public boolean onTouchEvent(MotionEvent event) {
            int action=event.getAction();
            float touchX=event.getX();
            float touchY=event.getY();
            switch (action)
            {
                case MotionEvent.ACTION_DOWN:
                    drawPath.moveTo(touchX,touchY);
                    break;
                case MotionEvent.ACTION_MOVE:
                    drawPath.lineTo(touchX,touchY);
                    break;
                case MotionEvent.ACTION_UP:
                    drawPath.lineTo(touchX,touchY);
                    drawCanvas.drawPath(drawPath,drawPaint);
                    drawPath.reset();
                    break;
                default:
                    return false;
            }
            invalidate();
            return true;
        }
    

     

     

    Finally code will be like this:

     

     

    package com.a2dcanvasapplication;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.graphics.PorterDuff;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    
    /**
     * Created by keshav on 1/8/17.
     */
    
    public class CanvasPencilView extends View {
        private Path drawPath;
        private Paint drawPaint,canvasPaint;
        private Bitmap canvasBitmap;
        private Canvas drawCanvas;
    
        public CanvasPencilView(Context context, AttributeSet attributeSet) {
            super(context, attributeSet);
            setUpDrawing();
        }
    
        private void setUpDrawing() {
            drawPath = new Path();
            drawPaint = new Paint();
            drawPaint.setColor(Color.parseColor("#ff0000"));
            drawPaint.setAntiAlias(true);
            drawPaint.setStrokeWidth(20);
            drawPaint.setStyle(Paint.Style.STROKE);
            //drawPaint.setStrokeJoin(Paint.Join.ROUND);
            drawPaint.setStrokeCap(Paint.Cap.ROUND);
            canvasPaint = new Paint(Paint.DITHER_FLAG);
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            canvasBitmap=Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888);
            drawCanvas=new Canvas(canvasBitmap);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawBitmap(canvasBitmap,0,0,canvasPaint);
            canvas.drawPath(drawPath,drawPaint);
        }
    
        public void clearCanvas()
        {
            drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
            invalidate();
        }
    
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            int action=event.getAction();
            float touchX=event.getX();
            float touchY=event.getY();
            switch (action)
            {
                case MotionEvent.ACTION_DOWN:
                    drawPath.moveTo(touchX,touchY);
                    break;
                case MotionEvent.ACTION_MOVE:
                    drawPath.lineTo(touchX,touchY);
                    break;
                case MotionEvent.ACTION_UP:
                    drawPath.lineTo(touchX,touchY);
                    drawCanvas.drawPath(drawPath,drawPaint);
                    drawPath.reset();
                    break;
                default:
                    return false;
            }
            invalidate();
            return true;
        }
    }
    

     

     

    Now you need to create a xml file named as activity_sample.xml. Define this class as custom layout file. Code snippet will be like:

     

     

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <com.a2dcanvasapplication.CanvasPencilView
            android:id="@+id/canvasPencilView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/rLayoutIncludeBottom"
            android:layout_margin="5dp" />
    
        <RelativeLayout
            android:id="@+id/rLayoutIncludeBottom"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_alignParentBottom="true">
    
            <Button
                android:id="@+id/buttonClear"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="67dp"
                android:layout_marginStart="67dp"
                android:text="Clear" />
        </RelativeLayout>
    
    
    </RelativeLayout>
    

     

     

    Now in java file define contentview of activity to this layout.Code snippet will be like:

     

     

    public class SampleActivity extends AppCompatActivity {
        CanvasPencilView touchAppView;
        Button btnClearCanvas;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            setContentView(R.layout.activity_sample);
            getSupportActionBar().hide();
            touchAppView=(CanvasPencilView) findViewById(R.id.canvasPencilView);
            btnClearCanvas=(Button)findViewById(R.id.buttonClear);
            btnClearCanvas.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    touchAppView.clearCanvas();
                }
            });
           
      }
    

     

     

    Now run and you will see output:

     

     

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------

     

     

    Next we will create object(image) dragging application

    we will create class named as TouchAppview which will extend View

    First we will initialize all primitive required 

     

     

     private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            private float x, y;
            private boolean touching, drawingTouch;
            Bitmap drawingBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.refer);
            int drawingpic_x = 0, drawingpic_y = 0;
            int drawingPicWidth = drawingBitmap.getWidth();
            int drawingPicHeight = drawingBitmap.getHeight();
            int drawingPicOffset_x = 0, drawingPicOffset_y = 0;
    

     

     

    In above x,y variable will be updated with coordinates got on screen touch

    boolean touching is for updating when screen is touched or not and drawingTouch is for updating either object is touched or not 

    drawingpic_x,drawingpic_y are initial positions for bitmap drawn .

    Next we will create constructor.

     

     

     public TouchAppView(Context context) {
                super(context);
            }
    

     

     

    Next there will be onDraw() method which will draw bitmap on canvas with initial position.There will be onMeasure(int w,int h) which will be used by extending class to measure its components.Code snippet will be like:

     

     

    @Override
            protected void onDraw(Canvas canvas) {
                canvas.drawBitmap(drawingBitmap, drawingpic_x, drawingpic_y, paint);
            }
    
            @Override
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),MeasureSpec.getSize(heightMeasureSpec));
            }
    

     

     

    Next there will be onTouchEvent(MotionEvent event) method which will intercept all touch responses as described above.Here in below method In Action_Down event there is a logic to check whether user has touched on object or not.So In Action_Move object will be dragged only if drawingTouch is true else not.Lastly invalidate() is called which removes the old view and redraw the canvas with dragged image on dragged position.Code snippet will be like:

     

     

         @Override
            public boolean onTouchEvent(MotionEvent event) {
                int action = event.getAction();
                switch (action) {
                    case MotionEvent.ACTION_DOWN:
                        x = event.getX();
                        y = event.getY();
                        touching = true;
                        if ((x > drawingpic_x) && (x < drawingpic_x + drawingPicWidth)
                                && (y > drawingpic_y) && (y < drawingpic_y + drawingPicHeight)) {
                            drawingPicOffset_x = (int) x - drawingpic_x;
                            drawingPicOffset_y = (int) y - drawingpic_y;
                            drawingTouch = true;
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
                        x = event.getX();
                        y = event.getY();
                        touching = true;
                        if (drawingTouch) {
                            drawingpic_x = (int) x-drawingPicOffset_x;
                            drawingpic_y = (int) y-drawingPicOffset_y;
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                       /* drawingpic_x=0;
                        drawingpic_y=0;*/
                    default:
                        drawingTouch = false;
                        touching = false;
                }
                invalidate();
                return true;
            }
    

    Finally code will be like this:

    class TouchAppView extends View {
            private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            private float x, y;
            private boolean touching, drawingTouch;
            Bitmap drawingBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.refer);
            int drawingpic_x = 0, drawingpic_y = 0;
            int drawingPicWidth = drawingBitmap.getWidth();
            int drawingPicHeight = drawingBitmap.getHeight();
            int drawingPicOffset_x = 0, drawingPicOffset_y = 0;
    
            public TouchAppView(Context context) {
                super(context);
            }
    
            @Override
            protected void onDraw(Canvas canvas) {
                canvas.drawBitmap(drawingBitmap, drawingpic_x, drawingpic_y, paint);
            }
    
            @Override
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),MeasureSpec.getSize(heightMeasureSpec));
            }
    
            @Override
            public boolean onTouchEvent(MotionEvent event) {
                int action = event.getAction();
                switch (action) {
                    case MotionEvent.ACTION_DOWN:
                        x = event.getX();
                        y = event.getY();
                        touching = true;
                        if ((x > drawingpic_x) && (x < drawingpic_x + drawingPicWidth)
                                && (y > drawingpic_y) && (y < drawingpic_y + drawingPicHeight)) {
                            drawingPicOffset_x = (int) x - drawingpic_x;
                            drawingPicOffset_y = (int) y - drawingpic_y;
                            drawingTouch = true;
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
                        x = event.getX();
                        y = event.getY();
                        touching = true;
                        if (drawingTouch) {
                            drawingpic_x = (int) x-drawingPicOffset_x;
                            drawingpic_y = (int) y-drawingPicOffset_y;
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                       /* drawingpic_x=0;
                        drawingpic_y=0;*/
                    default:
                        drawingTouch = false;
                        touching = false;
                }
                invalidate();
                return true;
            }
        }
    

     

     

    Next run this in activity by assigning contentview of java file to custom class.Code snippet will be like:

     

     

    public class SampleActivity extends AppCompatActivity {
       
           @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            getSupportActionBar().hide();
            setContentView(new TouchAppView(this));
        }
    

     

     

    Now you will see output :drag image on touch

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

Tags: Mobileapps