Android - How to draw on view

Aakash Anuj picture Aakash Anuj · Dec 13, 2012 · Viewed 18.8k times · Source

I am tring to paint on my own view (R.id.view) but this code does not seem to have any effect. It is not allowing me to draw anything at all.

public class MainActivity extends Activity implements OnTouchListener
        {
Path mPath;
Canvas canvas;
Paint mPaint;
MaskFilter mEmboss;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        View view=(View)findViewById(R.id.view1);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(0xFFFF0000);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(12);

        canvas = null;
        //view.draw(canvas);
        mPath = new Path();
        Bitmap mBitmap;
        //Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        mBitmap = Bitmap.createBitmap(210, 170, Bitmap.Config.ARGB_8888);
        canvas = new Canvas(mBitmap);
        canvas.drawColor(0xFFAAAAAA);

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


        //canvas.drawPaint(mPaint);
        view.draw(canvas);
        canvas.drawPath(mPath, mPaint);


        mEmboss = new EmbossMaskFilter(new float[] { 1, 1, 1 },
                                       0.4f, 6, 3.5f);



        view.setOnTouchListener(new OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event) {
                float x = event.getX();
                float y = event.getY();
                Log.d("x", String.valueOf(x));
                Log.d("y", String.valueOf(y));

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        Log.d("a","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;
            }
        });

       // mBlur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
    }
    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;
        }
    }
    private void touch_up() {
        mPath.lineTo(mX, mY);
        // commit the path to our offscreen
        canvas.drawPath(mPath, mPaint);
        // kill this so we don't double draw
        mPath.reset();
    }





}

What do I do to use the freehanf finger paint on my own view?

Answer

dannyRods picture dannyRods · Dec 13, 2012

It would be best if you made a class that extended view, and set that to the content view, its more dynamic that way. also the Action_Move parameter gets called a lot during touch events, so it might be best to take note of that, otherwise you'll get a straight line when you wanted a curve.

Edit:
You would start off in the onCreate by changing
View view = new MyView();
setContentView(view);

Inside of your MyView class you would have an arrayList of 'Path' objects, everytime Action_UP gets called, you add the path to the arrayList, use view.Invalidate(); and then the class will call the onDraw Method in your view class. So you override it like so.

@Override public void onDraw(Canvas c){
for(Path p: listOfPaths){
c.drawPath(p, paint);}
}

Note:This would be good for simple drawing, don't expect to draw the mona lisa on your tablet or phone with this method since once there are many lines you might notice a lag. If you want to get more complicated and professional. Check out the view.Invalidate(Rect r) approach to it, which wont invalidate the whole view but only the portion you just drew