How to make an ImageView with rounded corners?

前端 未结 30 2473
天涯浪人
天涯浪人 2020-11-21 05:39

In Android, an ImageView is a rectangle by default. How can I make it a rounded rectangle (clip off all 4 corners of my Bitmap to be rounded rectangles) in the ImageView?

相关标签:
30条回答
  • 2020-11-21 06:28

    A quick xml solution -

    <android.support.v7.widget.CardView
                android:layout_width="40dp"
                android:layout_height="40dp"
                app:cardElevation="0dp"
                app:cardCornerRadius="4dp">
    
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/rounded_user_image"
            android:scaleType="fitXY"/>
    
    </android.support.v7.widget.CardView>
    

    You can set your desired width, height and radius on CardView and scaleType on ImageView.

    With AndroidX, use <androidx.cardview.widget.CardView>

    0 讨论(0)
  • 2020-11-21 06:29

    Romain Guy is where it's at.

    Minified version as follows.

    Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.image)).getBitmap();
    
    Bitmap bitmapRounded = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
    Canvas canvas = new Canvas(bitmapRounded);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
    canvas.drawRoundRect((new RectF(0.0f, 0.0f, bitmap.getWidth(), bitmap.getHeight())), 10, 10, paint);
    
    imageView.setImageBitmap(bitmapRounded);
    
    0 讨论(0)
  • 2020-11-21 06:30

    I found that both methods were very helpful in coming up with a working solution. Here is my composite version, that is pixel independent and allows you to have some square corners with the rest of the corners having the same radius (which is the usual use case). With thanks to both of the solutions above:

    public static Bitmap getRoundedCornerBitmap(Context context, Bitmap input, int pixels , int w , int h , boolean squareTL, boolean squareTR, boolean squareBL, boolean squareBR  ) {
    
        Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final float densityMultiplier = context.getResources().getDisplayMetrics().density;
    
        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, w, h);
        final RectF rectF = new RectF(rect);
    
        //make sure that our rounded corner is scaled appropriately
        final float roundPx = pixels*densityMultiplier;
    
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
    
    
        //draw rectangles over the corners we want to be square
        if (squareTL ){
            canvas.drawRect(0, h/2, w/2, h, paint);
        }
        if (squareTR ){
            canvas.drawRect(w/2, h/2, w, h, paint);
        }
        if (squareBL ){
            canvas.drawRect(0, 0, w/2, h/2, paint);
        }
        if (squareBR ){
            canvas.drawRect(w/2, 0, w, h/2, paint);
        }
    
    
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(input, 0,0, paint);
    
        return output;
    }
    

    Also, I overrode ImageView to put this in so I could define it in xml. You may want to add in some of the logic that the super call makes here, but I've commented it as it's not helpful in my case.

        @Override
    protected void onDraw(Canvas canvas) {
        //super.onDraw(canvas);
            Drawable drawable = getDrawable();
    
            Bitmap b =  ((BitmapDrawable)drawable).getBitmap() ;
            Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
    
            int w = getWidth(), h = getHeight();
    
    
            Bitmap roundBitmap =  CropImageView.getRoundedCornerBitmap( getContext(), bitmap,10 , w, h , true, false,true, false);
            canvas.drawBitmap(roundBitmap, 0,0 , null);
    }
    

    Hope this helps!

    0 讨论(0)
  • 2020-11-21 06:30

    You should extend ImageView and draw your own rounded rectangle.

    If you want a frame around the image you could also superimpose the rounded frame on top of the image view in the layout.

    [edit]Superimpose the frame on to op the original image, by using a FrameLayout for example. The first element of the FrameLayout will be the image you want to diplay rounded. Then add another ImageView with the frame. The second ImageView will be displayed on top of the original ImageView and thus Android will draw it's contents above the orignal ImageView.

    0 讨论(0)
  • 2020-11-21 06:31

    This pure xml solution was good enough in my case. http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

    EDIT

    Here's the answer in a nutshell:

    In the /res/drawable folder, create a frame.xml file. In it, we define a simple rectangle with rounded corners and a transparent center.

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
         <solid android:color="#00ffffff" />
         <padding android:left="6dp"
            android:top="6dp"
            android:right="6dp"
            android:bottom="6dp" />
         <corners android:radius="12dp" />
         <stroke android:width="6dp" android:color="#ffffffff" />
    </shape>
    

    In your layout file you add a LinearLayout that contains a standard ImageView, as well as a nested FrameLayout. The FrameLayout uses padding and the custom drawable to give the illusion of rounded corners.

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_gravity="center"
        android:gravity="center" 
        android:background="#ffffffff">
    
        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="6dp"
            android:src="@drawable/tr"/>
    
        <FrameLayout 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
    
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:padding="6dp"
                android:src="@drawable/tr"/>
    
            <ImageView 
                 android:src="@drawable/frame"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent" />
    
        </FrameLayout>
    
    </LinearLayout>
    
    0 讨论(0)
  • 2020-11-21 06:31

    None of the methods provided in the answers worked for me. I found the following way works if your android version is 5.0 or above:

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    
                        ViewOutlineProvider provider = new ViewOutlineProvider() {
                            @Override
                            public void getOutline(View view, Outline outline) {
                                int curveRadius = 24;
                                outline.setRoundRect(0, 0, view.getWidth(), (view.getHeight()+curveRadius), curveRadius);
                            }
                        };
                        imageview.setOutlineProvider(provider);
                        imageview.setClipToOutline(true);
            }   
    

    No xml shapes to be defined, and the code above create corners only for top, which normal methods won't work. If you need 4 corners to be rounded, remove:

    "+ curveRadius"  
    

    From the parameter for bottom in setRoundRect. You can further expand the shape to any others by specifying outlines that suit your needs. Check out the following link:

    Android Developer Documentation.

    0 讨论(0)
提交回复
热议问题