How to make an ImageView with rounded corners?

前端 未结 30 2541
天涯浪人
天涯浪人 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:19

    Why not do clipping in draw()?

    Here is my solution:

    • Extend RelativeLayout with clipping
    • Put ImageView (or other views) into the layout:

    Code:

    public class RoundRelativeLayout extends RelativeLayout {
    
        private final float radius;
    
        public RoundRelativeLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            TypedArray attrArray = context.obtainStyledAttributes(attrs,
                    R.styleable.RoundRelativeLayout);
            radius = attrArray.getDimension(
                    R.styleable.RoundRelativeLayout_radius, 0);
        }
    
        private boolean isPathValid;
        private final Path path = new Path();
    
        private Path getRoundRectPath() {
            if (isPathValid) {
                return path;
            }
    
            path.reset();
    
            int width = getWidth();
            int height = getHeight();
            RectF bounds = new RectF(0, 0, width, height);
    
            path.addRoundRect(bounds, radius, radius, Direction.CCW);
            isPathValid = true;
            return path;
        }
    
        @Override
        protected void dispatchDraw(Canvas canvas) {
            canvas.clipPath(getRoundRectPath());
            super.dispatchDraw(canvas);
        }
    
        @Override
        public void draw(Canvas canvas) {
            canvas.clipPath(getRoundRectPath());
            super.draw(canvas);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
            int oldWidth = getMeasuredWidth();
            int oldHeight = getMeasuredHeight();
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
            int newWidth = getMeasuredWidth();
            int newHeight = getMeasuredHeight();
            if (newWidth != oldWidth || newHeight != oldHeight) {
                isPathValid = false;
            }
        }
    
    }
    
    0 讨论(0)
  • 2020-11-21 06:20

    Kotlin

    import android.graphics.BitmapFactory
    import android.os.Bundle
    import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory
    import kotlinx.android.synthetic.main.activity_main.*
    
    val bitmap = BitmapFactory.decodeResource(resources, R.drawable.myImage)
    val rounded = RoundedBitmapDrawableFactory.create(resources, bitmap)
    rounded.cornerRadius = 20f
    profileImageView.setImageDrawable(rounded)
    

    To make ImageView Circular we can change cornerRadius with:

    rounded.isCircular = true
    
    0 讨论(0)
  • 2020-11-21 06:20

    Answer for the question that is redirected here: "How to create a circular ImageView in Android?"

    public static Bitmap getRoundBitmap(Bitmap bitmap) {
    
        int min = Math.min(bitmap.getWidth(), bitmap.getHeight());
    
        Bitmap bitmapRounded = Bitmap.createBitmap(min, min, 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, min, min)), min/2, min/2, paint);
    
        return bitmapRounded;
    }
    
    0 讨论(0)
  • 2020-11-21 06:21

    Apply a shape to your imageView as below:

    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle" >
        <solid android:color="#faf5e6" />
        <stroke
            android:width="1dp"
            android:color="#808080" />
        <corners android:radius="15dp" />
        <padding
            android:bottom="5dp"
            android:left="5dp"
            android:right="5dp"
            android:top="5dp" />
    </shape>
    

    it may be helpful to you friend.

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

    The following creates a rounded rectangle layout object that draws a rounded rectangle around any child objects that are placed in it. It also demonstrates how to create views and layouts programmatically without using the layout xml files.

    package android.example;
    
    import android.app.Activity;
    import android.graphics.Color;
    import android.os.Bundle;
    import android.util.DisplayMetrics;
    import android.util.TypedValue;
    import android.view.ViewGroup.LayoutParams;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    
    public class MessageScreen extends Activity {
     /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      int mainBackgroundColor = Color.parseColor("#2E8B57");
      int labelTextColor = Color.parseColor("#FF4500");
      int messageBackgroundColor = Color.parseColor("#3300FF");
      int messageTextColor = Color.parseColor("#FFFF00");
    
      DisplayMetrics metrics = new DisplayMetrics();
      getWindowManager().getDefaultDisplay().getMetrics(metrics);
      float density = metrics.density;
      int minMarginSize = Math.round(density * 8);
      int paddingSize = minMarginSize * 2;
      int maxMarginSize = minMarginSize * 4;
    
      TextView label = new TextView(this);
      /*
       * The LayoutParams are instructions to the Layout that will contain the
       * View for laying out the View, so you need to use the LayoutParams of
       * the Layout that will contain the View.
       */
      LinearLayout.LayoutParams labelLayoutParams = new LinearLayout.LayoutParams(
        LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
      label.setLayoutParams(labelLayoutParams);
      label.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
      label.setPadding(paddingSize, paddingSize, paddingSize, paddingSize);
      label.setText(R.string.title);
      label.setTextColor(labelTextColor);
    
      TextView message = new TextView(this);
      RoundedRectangle.LayoutParams messageLayoutParams = new RoundedRectangle.LayoutParams(
     LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
      /*
       * This is one of the calls must made to force a ViewGroup to call its
       * draw method instead of just calling the draw method of its children.
       * This tells the RoundedRectangle to put some extra space around the
       * View.
       */
      messageLayoutParams.setMargins(minMarginSize, paddingSize,
        minMarginSize, maxMarginSize);
      message.setLayoutParams(messageLayoutParams);
      message.setTextSize(TypedValue.COMPLEX_UNIT_SP, paddingSize);
      message.setText(R.string.message);
      message.setTextColor(messageTextColor);
      message.setBackgroundColor(messageBackgroundColor);
    
      RoundedRectangle messageContainer = new RoundedRectangle(this);
      LinearLayout.LayoutParams messageContainerLayoutParams = new LinearLayout.LayoutParams(
        LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
      messageContainerLayoutParams.setMargins(paddingSize, 0, paddingSize, 0);
      messageContainer.setLayoutParams(messageContainerLayoutParams);
      messageContainer.setOrientation(LinearLayout.VERTICAL);
      /*
       * This is one of the calls must made to force a ViewGroup to call its
       * draw method instead of just calling the draw method of its children.
       * This tells the RoundedRectangle to color the the exta space that was
       * put around the View as well as the View. This is exterior color of
       * the RoundedRectangle.
       */
      messageContainer.setBackgroundColor(mainBackgroundColor);
      /*
       * This is one of the calls must made to force a ViewGroup to call its
       * draw method instead of just calling the draw method of its children.
       * This is the interior color of the RoundedRectangle. It must be
       * different than the exterior color of the RoundedRectangle or the
       * RoundedRectangle will not call its draw method.
       */
      messageContainer.setInteriorColor(messageBackgroundColor);
      // Add the message to the RoundedRectangle.
      messageContainer.addView(message);
    
      //
      LinearLayout main = new LinearLayout(this);
      LinearLayout.LayoutParams mainLayoutParams = new LinearLayout.LayoutParams(
        LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
      main.setLayoutParams(mainLayoutParams);
      main.setOrientation(LinearLayout.VERTICAL);
      main.setBackgroundColor(mainBackgroundColor);
      main.addView(label);
      main.addView(messageContainer);
    
      setContentView(main);
     }
    }
    

    The class for RoundedRectangle layout object is as defined here:

    /**
     *  A LinearLayout that draws a rounded rectangle around the child View that was added to it.
     */
    package android.example;
    
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.RectF;
    import android.util.AttributeSet;
    import android.util.DisplayMetrics;
    import android.widget.LinearLayout;
    
    /**
     * A LinearLayout that has rounded corners instead of square corners.
     * 
     * @author Danny Remington
     * 
     * @see LinearLayout
     * 
     */
    public class RoundedRectangle extends LinearLayout {
     private int mInteriorColor;
    
     public RoundedRectangle(Context p_context) {
      super(p_context);
     }
    
     public RoundedRectangle(Context p_context, AttributeSet attributeSet) {
      super(p_context, attributeSet);
     }
    
     // Listener for the onDraw event that occurs when the Layout is drawn.
     protected void onDraw(Canvas canvas) {
      Rect rect = new Rect(0, 0, getWidth(), getHeight());
      RectF rectF = new RectF(rect);
      DisplayMetrics metrics = new DisplayMetrics();
      Activity activity = (Activity) getContext();
      activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
      float density = metrics.density;
      int arcSize = Math.round(density * 10);
    
      Paint paint = new Paint();
      paint.setColor(mInteriorColor);
    
      canvas.drawRoundRect(rectF, arcSize, arcSize, paint);
     }
    
     /**
      * Set the background color to use inside the RoundedRectangle.
      * 
      * @param Primitive int - The color inside the rounded rectangle.
      */
     public void setInteriorColor(int interiorColor) {
      mInteriorColor = interiorColor;
     }
    
     /**
      * Get the background color used inside the RoundedRectangle.
      * 
      * @return Primitive int - The color inside the rounded rectangle.
      */
     public int getInteriorColor() {
      return mInteriorColor;
     }
    
    }
    
    0 讨论(0)
  • 2020-11-21 06:22

    Thanks a lot to first answer. Here is modified version to convert a rectangular image into a square one (and rounded) and fill color is being passed as parameter.

    public static Bitmap getRoundedBitmap(Bitmap bitmap, int pixels, int color) {
    
        Bitmap inpBitmap = bitmap;
        int width = 0;
        int height = 0;
        width = inpBitmap.getWidth();
        height = inpBitmap.getHeight();
    
        if (width <= height) {
            height = width;
        } else {
            width = height;
        }
    
        Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
    
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, width, height);
        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(inpBitmap, rect, rect, paint);
    
        return output;
    }
    
    0 讨论(0)
提交回复
热议问题