Domanda

I have an ImageView and I want to make it with rounded corners.

I use this:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> 
    <solid  android:color="@null"/>    

    <stroke android:width="1dp"
            android:color="#ff000000"/>


    <corners android:radius="62px"/> 
</shape>

And set this code as background of my imageview. It works, but the src image that I put on the ImageView is going out of the borders and doesn't adapt itself into the new shape.

How can I solve the problem?

È stato utile?

Soluzione

try this one :

public class CustomImageView extends ImageView {

    public static float radius = 18.0f;  

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

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

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

    @Override
    protected void onDraw(Canvas canvas) {
        //float radius = 36.0f;  
        Path clipPath = new Path();
        RectF rect = new RectF(0, 0, this.getWidth(), this.getHeight());
        clipPath.addRoundRect(rect, radius, radius, Path.Direction.CW);
        canvas.clipPath(clipPath);
        super.onDraw(canvas);
    }
}

and

<your.pack.name.CustomImageView
                android:id="@+id/selectIcon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:scaleType="centerCrop" />

CustomImageView  iconImage = (CustomImageView )findViewById(R.id.selectIcon);
iconImage.setImageBitmap(bitmap);

or,

ImageView iv= new CustomImageView(this);
iv.setImageResource(R.drawable.pic);

Altri suggerimenti

It's strange that nobody here has mentioned RoundedBitmapDrawable from Android Support Library v4. For me it is the simplest way to get rounded corners without borders. Here is example of usage:

RoundedBitmapDrawable roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
final float roundPx = (float) bitmap.getWidth() * 0.06f;
roundedBitmapDrawable.setCornerRadius(roundPx);

Make one function which make rounded to your bitmap using canvas.

public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
            .getHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
    final RectF rectF = new RectF(rect);
    final float roundPx = pixels;

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, paint);

    return output;
}

for more info:> here

The accepted answer uses path clipping, but it doesn't support anti-aliasing. See Romain Guy's comments on his post. "path clipping does not support antialiasing and you get jagged edges."

http://www.curious-creature.com/2012/12/11/android-recipe-1-image-with-rounded-corners/

There is one good library(vinc3m1’s RoundedImageView) that supoorts rounded corners on ImageView, but it only supports the same radiuses on every corners. So I made one that you can set different radiuses on each corners.

It doesn't rely on path clipping, nor redrawing. It only draws one time with canvas.drawPath() method. So I finally got result that I wanted like below.

enter image description here

See : https://github.com/pungrue26/SelectableRoundedImageView

If you need make Bitmap with different corner radii and I recommend follow code:

private static Bitmap createRoundedRectBitmap(@NonNull Bitmap bitmap,
                                float topLeftCorner, float topRightCorner,
                                float bottomRightCorner, float bottomLeftCorner) {
    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), 
                                        Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final int color = Color.WHITE;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
    final RectF rectF = new RectF(rect);
    Path path = new Path();
    float[] radii = new float[]{
            topLeftCorner, bottomLeftCorner,
            topRightCorner, topRightCorner,
            bottomRightCorner, bottomRightCorner,
            bottomLeftCorner, bottomLeftCorner
    };

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    path.addRoundRect(rectF, radii, Path.Direction.CW);
    canvas.drawPath(path, paint);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, paint);
    return output;
}

If you need border also then: 1. You can use a rounded box image with a transparent body and white from outside. For Example:

Rounded box

and use this with target image like below:

<FrameLayout
android:layout_width="100px"
android:layout_height="100px" >
<ImageView
        android:id="@+id/targetImage"
        android:layout_width="100px"
        android:layout_height="100px"
        android:src="@drawable/app_icon"
        android:layout_gravity="center" />
<ImageView
        android:id="@+id/boxImage"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="fitXY"
        android:src="@drawable/box" />

  1. Adding CardView as parent layout of ImageView also be a good solution.

For me, the below method does the magic. :) This method accepts a bitmap object and returns it back with rounded corners. roundPx is the number of rounded pixels you want:

public static Bitmap getRoundedCornerBitmap(Bitmap bitmap) {
    Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
    bitmap.getHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
    final RectF rectF = new RectF(rect);
    final float roundPx = 12;

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(bitmap, rect, rect, paint);

    return output;
}

...or you could use this library instead of ImageView without any further coding.

It can be done with background drawable, like explain in many posts including this one, but it also needs to set clipping. Here a full example:

The code:

AppCompatImageView iconView = findViewById(R.id.thumbnail);
iconView.setClipToOutline(true);

The layout:

<android.support.v7.widget.AppCompatImageView
    android:id="@+id/thumbnail"
    android:layout_width="80dp"
    android:layout_height="80dp"
    android:contentDescription="@string/thumbnail"
    android:scaleType="centerInside"
    android:background="@drawable/round_view" <!--here set the drawable as background -->
    tools:src="@mipmap/ic_user" />

The drawable:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="10dp" />
</shape>
/**
 * Creates new circular bitmap based on original one.
 * @param newCornerRadius is optional
 */
fun Bitmap.toCircular(context: Context, newCornerRadius: Float? = null): RoundedBitmapDrawable {
    return RoundedBitmapDrawableFactory.create(context.resources, this).apply {
        isCircular = true
        newCornerRadius?.let {
            cornerRadius = it
        }
    }
}
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) {

        super.onDraw(canvas);

        Bitmap rounder = Bitmap.createBitmap(getWidth(),getHeight(),Bitmap.Config.ARGB_8888);
        Canvas canvasRound = new Canvas(rounder);    

        Paint xferPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        xferPaint.setColor(Color.BLACK);

        final int rx = this.getWidth(); //our x radius
        final int ry = this.getHeight(); //our y radius

        canvasRound.drawRoundRect(new RectF(0,0,rx,ry), rx, ry, xferPaint);     

        xferPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

        canvas.drawBitmap(rounder, 0, 0, xferPaint);

    }

}

The method to make rounded corners for imageview in android is not rocket science guys! just use a png with required curves with the same color as your background and set the overlay to FITXY.!

public void drawRoundImage(boolean isEditPicEnable){
   if(originalImageBitmap != null){
        setBackgroundResource(R.drawable.ic_account_user_outer_circle_blue);

        if (isEditPicEnable) {
            setBackgroundResource(R.drawable.ic_account_user_outer_circle_white);
            Bitmap mask = BitmapFactory.decodeResource(getResources(), R.drawable.ic_account_white_mask);
            Bitmap mask1 = BitmapFactory.decodeResource(getResources(), R.drawable.ic_account_pencil_bg);
            originalImageBitmap = Bitmap.createScaledBitmap(originalImageBitmap, mask.getWidth(), mask.getHeight(), true);
            Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas mCanvas = new Canvas(result);
            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
            mCanvas.drawBitmap(originalImageBitmap, 0, 0, null);
            mCanvas.drawBitmap(mask, 0, 0, paint);
            mCanvas.drawBitmap(mask1, 0, 0, null);
            Bitmap mask2 = BitmapFactory.decodeResource(getResources(), R.drawable.ic_account_pencil);
            mCanvas.drawBitmap(mask2, 0, 0, null);
            setImageBitmap(result);
            setScaleType(ScaleType.FIT_XY);
        } else {
            Bitmap mask = BitmapFactory.decodeResource(getResources(),R.drawable.ic_account_white_mask);
            originalImageBitmap = Bitmap.createScaledBitmap(originalImageBitmap, mask.getWidth(),mask.getHeight(), true);
            Bitmap result = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(),Bitmap.Config.ARGB_8888);
            Canvas mCanvas = new Canvas(result);
            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
            mCanvas.drawBitmap(originalImageBitmap, 0, 0, null);
            mCanvas.drawBitmap(mask, 0, 0, paint);
            paint.setXfermode(null);
            setImageBitmap(result);
            setScaleType(ScaleType.FIT_XY);
        }

    }else{
        setBackgroundResource(R.drawable.ic_account_user_outer_circle_blue);
        setImageResource(R.drawable.my_ac_default_profile_pic);
    }

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top