Android: Drawing a canvas to an ImageView Android: Drawing a canvas to an ImageView android android

Android: Drawing a canvas to an ImageView


I had the same challenge and came to the conclusion that overwriting onDraw will at least in the general case not work. My blog explains the reasons. What worked very well for me is the following:

  1. Create a new image bitmap and attach a brand new canvas to it.
  2. Draw the image bitmap into the canvas.
  3. Draw everything else you want into the canvas.
  4. Attach the canvas to the ImageView.

Here is a code snippet for this:

import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.RectF;import android.graphics.drawable.BitmapDrawable;ImageView myImageView = ...Bitmap myBitmap = ...Paint myRectPaint = ...int x1 = ...int y1 = ...int x2 = ...int y2 = ...//Create a new image bitmap and attach a brand new canvas to itBitmap tempBitmap = Bitmap.createBitmap(myBitmap.getWidth(), myBitmap.getHeight(), Bitmap.Config.RGB_565);Canvas tempCanvas = new Canvas(tempBitmap);//Draw the image bitmap into the cavastempCanvas.drawBitmap(myBitmap, 0, 0, null);//Draw everything else you want into the canvas, in this example a rectangle with rounded edgestempCanvas.drawRoundRect(new RectF(x1,y1,x2,y2), 2, 2, myPaint);//Attach the canvas to the ImageViewmyImageView.setImageDrawable(new BitmapDrawable(getResources(), tempBitmap));


     ImageView imageView=(ImageView) findViewById(R.id.image);        Bitmap bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);            Canvas canvas = new Canvas(bitmap);        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);        paint.setColor(Color.BLACK);        canvas.drawCircle(50, 50, 10, paint);        imageView.setImageBitmap(bitmap);


I think that a better approach would be to create a custom ImageView and Override the onDraw method. Something like:

public class CustomView extends ImageView {public CustomView(Context context) {    super(context);}public CustomView(Context context, AttributeSet attrst) {    super(context, attrst);}public CustomView(Context context, AttributeSet attrs, int defStyle) {    super(context, attrs, defStyle);}MyBitmapFactory bitMapFac = null;public void setBitmapFactory(MyBitmapFactory bitMapFac){    this.bitMapFac = bitMapFac;}@Overridepublic void onDraw(Canvas canvas) {    canvas.drawColor(Color.TRANSPARENT);    /*instantiate a bitmap and draw stuff here, it could well be another    class which you systematically update via a different thread so that you can get a fresh updated    bitmap from, that you desire to be updated onto the custom ImageView.    That will happen everytime onDraw has received a call i.e. something like:*/    Bitmap myBitmap = bitMapFac.update(); //where update returns the most up  to date Bitmap    //here you set the rectangles in which you want to draw the bitmap and pass the bitmap            canvas.drawBitmap(myBitMap, new Rect(0,0,400,400), new Rect(0,0,240,135) , null);    super.onDraw(canvas);    //you need to call postInvalidate so that the system knows that it  should redraw your custom ImageView    this.postInvalidate();}}

It would be a good idea to implement some logic that checks if there is a fresh bitmap to acquire via the update() method, so that the code inside onDraw won't execute every time and put overhead to the system.

And then use your custom view wherever you need it. The easiest way would be to declare it directly inside the activity_layout.xml as such:

   <com.mycustomviews.CustomView        android:id="@+id/customView"        android:layout_centerInParent="true"        android:layout_height="135dp"        android:layout_width="240dp"       android:background="@android:color/transparent"/>

And then access is in your code like any other view by using:

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