Mulgard
Mulgard

Reputation: 10589

RoundedImageView does not round image when used in layout file

I have the following RoundedImageView:

public class RoundedImageView extends ImageView {

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

    public RoundedImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

    @Override
    protected void onDraw(Canvas canvas) {
        if (this.getDrawable() == null) {
            return;
        }

        if (this.getWidth() == 0 || this.getHeight() == 0) {
            return;
        }

        Bitmap bitmapDrawable = ((BitmapDrawable) this.getDrawable()).getBitmap();
        Bitmap bitmap = bitmapDrawable.copy(Bitmap.Config.ARGB_8888, true);

        int width = this.getWidth(); 

        Bitmap roundBitmap = getCroppedBitmap(bitmap, width);
        canvas.drawBitmap(roundBitmap, 0, 0, null);
    }

    public static Bitmap getCroppedBitmap(Bitmap bitmap, int radius) {
        Bitmap scaledBitmap = null;

        if (bitmap.getWidth() != radius || bitmap.getHeight() != radius) {
            float smallest = Math.min(bitmap.getWidth(), bitmap.getHeight());
            float factor = smallest / radius;

            scaledBitmap = Bitmap.createScaledBitmap(bitmap, (int)(bitmap.getWidth() / factor), (int)(bitmap.getHeight() / factor), false);
        } else {
            scaledBitmap = bitmap;
        }

        Bitmap output = Bitmap.createBitmap(radius, radius, Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, radius, radius);

        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        paint.setDither(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(Color.parseColor("#BAB399"));
        canvas.drawCircle(radius / 2 + 0.7f, radius / 2 + 0.7f, radius / 2 + 0.1f, paint);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(scaledBitmap, rect, rect, paint);

        return output;
    }
}

When i use this RoundedImageView from code like in the followin it works perfectly:

    RelativeLayout.LayoutParams layoutParamsImageProfile = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
    layoutParamsImageProfile.addRule(RelativeLayout.ABOVE, bottomDummyID);
    layoutParamsImageProfile.addRule(RelativeLayout.LEFT_OF, rightDummyID);

    RoundedImageView imageViewProfile = new RoundedImageView(this.getActivity());
    imageViewProfile.setLayoutParams(layoutParamsImageProfile);
    imageViewProfile.setImageDrawable(Helper.loadDrawableFromFile(this.getResources(), Helper.getProfileMenuImagePath()));

When i use it from layout file like this:

<de.myproject.views.RoundedImageView
    android:id="@+id/profile_common_imageview_profile"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginEnd="20dp"
    android:contentDescription="@string/text_description" />

The images are not rounded. They remain rectangles. Why isnt the mechanic working from layout, just from code?

Upvotes: 0

Views: 261

Answers (1)

Vesko
Vesko

Reputation: 3760

I cannot answer to your original question, however I can tell you that your onDraw() method is way too heavy the way it's written right now! You know this method is going to be called A LOT of times, so it must be as fast as possible.

If you want to achieve rounder corders, I'd suggest you read a THIS RECIPE from Romain Guy (was core Android developer). It has MANY performance advantages compared to your code.

Also you can take a look at a THIS LIBRARY which claims it's based on Romain Guy's method.

Upvotes: 1

Related Questions