3

I have made a custom view which is refereed from xml layout. I added a button for clearing the view. Now I want to clear the canvas area upon clicking. I added an onClick event in xml layout file.Now how n where do I add the code for clearing the whole view/canvas? I have just added few portion of code. (this is not clearing anything). I have added my activity,view and layout file in order as below.

public class CustomViewActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

    }

    public void clearLine(View v) {

    new CustomView(CustomViewActivity.this, null).clearCanvas();        
  } 

}

public class CustomView extends View {

    private Paint paint = new Paint();
      private Path path = new Path();
      public Boolean clearCanvas = false;

      public CustomView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);         
        }

    public CustomView(Context context,AttributeSet attrs ) {
        super(context,attrs);
        paint.setAntiAlias(true);
        paint.setColor(Color.BLUE);
        paint.setTextSize(20);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeWidth(5f);
    }

    protected void onDraw(Canvas canvas) {
    if(clearCanvas)
        {  // Choose the colour you want to clear with.
            canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
            //canvas.drawColor(0, Mode.CLEAR);
            clearCanvas = false;            
        }

        super.onDraw(canvas);
        canvas.drawText("Hello World", 5, 30, paint);
        canvas.drawPath(path, paint);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

    //int action = event.getAction() & MotionEvent.ACTION_MASK;

       float eventX = event.getX();
        float eventY = event.getY();

        switch (event.getAction()) {
          case MotionEvent.ACTION_DOWN:
            path.moveTo(eventX, eventY);

            return true;
          case MotionEvent.ACTION_MOVE: 
            path.lineTo(eventX, eventY);
            break;
          case MotionEvent.ACTION_UP:
            // nothing to do 
           break;
          default:
            return false;
        }

        // Schedules a repaint.
        invalidate();
        return true;

    }
    public void clearCanvas(){

            clearCanvas = true;
            postInvalidate();
            //canvas.drawColor(0, Mode.CLEAR);

        }

}

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >


           <com.example.CustomViewEvent.CustomView
               android:id="@+id/customView"
               android:layout_width="fill_parent"
               android:layout_height="wrap_content" />

           <Button
               android:id="@+id/button1"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_alignParentBottom="true"
               android:layout_centerHorizontal="true"
               android:layout_marginBottom="28dp"
               android:onClick="clearLine"
               android:text="CLEAR" />

</RelativeLayout>
Tanvir
  • 1,642
  • 8
  • 32
  • 53

1 Answers1

5

What you need to do is access the canvas in the onDraw method.

So if you use a global variable, in your button click method, and set it to true. In OnDraw you can check its status and clear canvas if necessary. (Then set it back to false so it doesnt do it every time).

See code below for usage.

public Boolean clearCanvas = false;

protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(clearCanvas)
        {  // Choose the colour you want to clear with.
            canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
            clearCanvas = false;
        }
        canvas.drawPath(path, paint);       
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

    float eventX = event.getX();
        float eventY = event.getY();

        switch (event.getAction()) {
          case MotionEvent.ACTION_DOWN:
            path.moveTo(eventX, eventY);

            return true;
          case MotionEvent.ACTION_MOVE: 
            path.lineTo(eventX, eventY);
            break;
          case MotionEvent.ACTION_UP:
            // nothing to do 
           break;
          default:
            return false;
        }

        // Schedules a repaint.
        invalidate();
        return true;

    }
// this is the method which will be invoked from main activity class for clearing whatever //is in the view/canvas 
         public void clearCanvas(){

            //canvas.drawColor(0, Mode.CLEAR);

            clearCanvas = true;
            invalidate();
        }

}

EDIT: Looking at your new code I see a few problems.

I think it revoles around the fact you are not clearing the correct view.

First off, obtain the instance of the existing view. Then you can clear it. Rather than the wrong non existing instance of it.

 CustomView cv = (CustomView)findViewById(R.id.customView); 
 cv.clearCanvas();   

Try invalidate(); else postInvalidate(); One should work.

postInvalidate() is for when you are running on a non UI Thread.

IAmGroot
  • 13,760
  • 18
  • 84
  • 154
  • PorterDuff in PorterDuff.Mode.CLEAR); is giving an error. What is this PorterDuff. – Tanvir Sep 30 '12 at 04:59
  • I invoked the method-clearCanvas() from the activity's onclik method by this- new CustomView(CustomViewActivity.this, null).clearCanvas(); YET its not even calling the onDraw() again upon invoking invalidate(). } – Tanvir Sep 30 '12 at 05:19
  • you can try `postInvalidate()`. Use just `Mode.CLEAR` if its valid. Im not sure what your structure is like, but my `onDraw` is called in a gaming loop. The fact that invalidate is not working, is another question. You might get better answers opening a new one. – IAmGroot Sep 30 '12 at 07:24
  • WOULD you pls look at the whole code again above. I edited my post/ Pls look above. – Tanvir Sep 30 '12 at 12:00
  • I dont quite follow it. You are using a view, not a surface view. And the onDraw method is not overriden from anything. So unless you call it its not doing anything. But you need to grab a canvas and pass it to it. But your using a view! Not SurfaceView. – IAmGroot Sep 30 '12 at 13:05
  • I dont know how onDraw() isnt overridden in my code.The code is drawing the text "Hello World" means onDraw() is called once in the beginning. How do I grab a canvas object which is drawing. BTW I m new to android, I have no idea abt surface view. Cud you change the code the way it should work. Thanx. – Tanvir Oct 01 '12 at 08:54
  • @Tanvir See edit, I think its just the last bit Defining CustomView properly that you need to do. – IAmGroot Oct 01 '12 at 09:06
  • 1
    Extremely SORRY for LATE REPLY. (I was sick for several days). Now back to work again. Thanx for ur reply. The altered code is not clearing the canvas area, instead its just making the background of the canvas BLACK whereas the drawn lines are still there. (my default background is white). Thanx – Tanvir Oct 04 '12 at 15:32