Search code examples
androidcanvasbitmappaint

Android Canvas focus in selected area


I'm trying to achieve this effect:

enter image description here

The idea is that I want to cover an ImageView with a partial transparent layer, but not all of it. Somewhere there is an area (circle or rectangle), that should be completely transparent. I tried it using this lines of code:

Paint paint = new Paint();
paint.setColor(Color.parseColor("#80000000"));
canvas.drawRect(0, 0, bitmap.getWidth(), bitmap.getHeight(), paint);
paint.setColor(Color.TRANSPARENT);
canvas.drawCircle((int) x, (int) y, 50, paint);

but it didn't work since under the circle there is the rectangle. Is there anyway to achieve what I'm trying to?


Solution

  • Sorry for the late answer. You can achieve this my making a CustomImageView and do as follow.

    public class CustomImageView extends ImageView {
    
    private Paint paint;
    private Paint transParentPaint;
    private Canvas tempCanvas;
    private Bitmap emptyBitmap;
    
    public CustomImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }
    
    public CustomImageView(Context context) {
        super(context);
        init();
    }
    
    public CustomImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    
    private void init() {
        paint = new Paint();
        paint.setColor(Color.parseColor("#80000000"));  //Semi TransParent Paint
    
        transParentPaint = new Paint();
        transParentPaint.setColor(Color.TRANSPARENT);
        transParentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));//This is necessary to make the portion transparent. Otherwise it will show Black.
    }
    
    
    @Override
    protected void onDraw(Canvas canvas) {
        emptyBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        tempCanvas = new Canvas(emptyBitmap);
        emptyBitmap.eraseColor(Color.TRANSPARENT);
        // tempCanvas.drawColor(Color.parseColor("#80000000"));
        tempCanvas.drawRect(0, 0, getWidth(), getHeight(), paint);
        tempCanvas.drawCircle(getWidth() / 2, getHeight() / 2, 100, transParentPaint); // Set the circle at the middle of the Canvas.
        canvas.drawBitmap(emptyBitmap, 0, 0, null);
    }
    

    }

    Add this CustomImageView to your layout file

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
    >
    
    <transparent.example.com.partialtransparentview.CustomImageView
        android:id="@+id/image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/your_image" />
    </RelativeLayout>
    

    It will work as you expected.