在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?


请注意,从2021年起,只需使用ShapeableImageView


当前回答

这种纯xml解决方案对我来说已经足够好了。http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

EDIT

以下是简单的答案:

在/res/drawable文件夹中,创建一个frame.xml文件。在其中,我们定义了一个具有圆角和透明中心的简单矩形。

<?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>

在你的布局文件中,你添加了一个线性布局,它包含一个标准的ImageView,以及一个嵌套的framayout。FrameLayout使用填充和自定义drawable来提供圆角的错觉。

<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>

其他回答

一个快速的xml解决方案-

<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>

你可以在CardView上设置你想要的宽度,高度和半径,在ImageView上设置scaleType。

对于AndroidX,使用< AndroidX .cardview.widget. cardview >

应用一个形状到你的imageView如下所示:

<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>

这可能对你的朋友有帮助。

使用这个得到圆形图像与边界

    public static Bitmap getCircularBitmapWithBorder(Bitmap bitmap, int bordercolor) {
    if (bitmap == null || bitmap.isRecycled()) {
        return null;
    }
    int borderWidth=(int)(bitmap.getWidth()/40);
    final int width = bitmap.getWidth() + borderWidth;
    final int height = bitmap.getHeight() + borderWidth;

    Bitmap canvasBitmap = Bitmap.createBitmap(width, height,
            Bitmap.Config.ARGB_8888);
    BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP,
            TileMode.CLAMP);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setShader(shader);

    Canvas canvas = new Canvas(canvasBitmap);
    float radius = width > height ? ((float) height) / 2f
            : ((float) width) / 2f;
    canvas.drawCircle(width / 2, height / 2, radius, paint);
    paint.setShader(null);
    paint.setStyle(Paint.Style.STROKE);
    paint.setColor(bordercolor);
    paint.setStrokeWidth(borderWidth);
    canvas.drawCircle(width / 2, height / 2, radius - borderWidth / 2,
            paint);
    return canvasBitmap;
}

以下是我的解决方案:

<com.myproject.ui.RadiusCornerImageView
        android:id="@+id/imageViewPhoto"
        android:layout_width="160dp"
        android:layout_height="160dp"
        app:corner_radius_dp="5"
        app:corner_radius_position="top"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

在java代码中:

public class RadiusCornerImageView extends android.support.v7.widget.AppCompatImageView {
    private int cornerRadiusDP = 0; // dp
    private int corner_radius_position;

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

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

    public RadiusCornerImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RadiusCornerImageView, 0, 0);
        try {
            cornerRadiusDP = typeArray.getInt(R.styleable.RadiusCornerImageView_corner_radius_dp, 0);
            corner_radius_position = typeArray.getInteger(R.styleable.RadiusCornerImageView_corner_radius_position, 0);
        } finally {
            typeArray.recycle();
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        float radiusPx = AndroidUtil.dpToPx(getContext(), cornerRadiusDP);
        Path clipPath = new Path();
        RectF rect = null;
        if (corner_radius_position == 0) { // all
            // round corners on all 4 angles
            rect = new RectF(0, 0, this.getWidth(), this.getHeight());
        } else if (corner_radius_position == 1) {
            // round corners only on top left and top right
            rect = new RectF(0, 0, this.getWidth(), this.getHeight() + radiusPx);

    } else {
        throw new IllegalArgumentException("Unknown corner_radius_position = " + corner_radius_position);
    }
    clipPath.addRoundRect(rect, radiusPx, radiusPx, Path.Direction.CW);
    canvas.clipPath(clipPath);
    super.onDraw(canvas);
 }
}

虽然前两个答案是可行的,但我希望再多描述一点。 比如说,ImageView所在的地方有一个活动或片段。您希望绘制图像并按比例缩放。然后你应该在onCreate或onCreateView中写入如下代码:

LinearLayout rootLayout = (LinearLayout) findViewById(R.id.rootLayout);
ImageView image = (ImageView) findViewById(R.id.image);
// Wait till an activity is visible and image can be measured.
rootLayout.post(new Runnable() {
    @Override
    public void run() {
        // Setting ImageView height with aspect ratio.
        Drawable drawable = ContextCompat.getDrawable(getActivity(), R.drawable.your_image);
        int height = getImageViewHeight(drawable, image);

        // Rounding image corners.
        float radius = getResources().getDimension(R.dimen.your_radius_in_dp);
        Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
        Bitmap result = getRoundedBitmap(bitmap, image.getWidth(), height, radius);
        image.setImageBitmap(result);
    }
});

其中设置新的图像高度为:

public static int getImageViewHeight(Drawable drawable, ImageView imageView) {
    imageView.setImageDrawable(drawable);
    int width = drawable.getIntrinsicWidth();
    int height = 0;
    if (width > 0) {
        height = (drawable.getIntrinsicHeight() * imageView.getWidth()) / width;
        imageView.getLayoutParams().height = height;
        imageView.requestLayout();
    }
    return height;
}

然后,您应该编写一个方法来缩放图像并使其圆角。这里的width和height是位图的新维度(更小或更大)。在下面的例子中,我只圆角上的两个角。

private Bitmap getRoundedBitmap(Bitmap bitmap, int width, int height, float radius) {
    // Create scaled bitmap.
    Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
    BitmapShader shader = new BitmapShader(scaledBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setShader(shader);

    Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(result);
    // First make all corners round.
    canvas.drawRoundRect(new RectF(0, 0, width, height), radius, radius, paint);
    // Then draw bottom rectangle.
    canvas.drawRect(0, height - radius, radius, height, paint);
    canvas.drawRect(width - radius, height - radius, width, height, paint);
    return result;
}