在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?
请注意,从2021年起,只需使用ShapeableImageView
在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?
请注意,从2021年起,只需使用ShapeableImageView
当前回答
下面是一个覆盖imageView的简单示例,然后你也可以在布局设计器中使用它来预览。
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 defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void setImageDrawable(Drawable drawable) {
float radius = 0.1f;
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
RoundedBitmapDrawable rid = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
rid.setCornerRadius(bitmap.getWidth() * radius);
super.setImageDrawable(rid);
}
}
这是为了快速解决问题。半径用于所有角落,并基于位图宽度的百分比。
我只是覆盖了setImageDrawable,并使用支持v4方法绘制圆角位图。
用法:
<com.example.widgets.RoundedImageView
android:layout_width="39dp"
android:layout_height="39dp"
android:src="@drawable/your_drawable" />
使用imageView和自定义imageView预览:
其他回答
对于那些使用Glide和Kotlin的,你可以通过扩展RequestBuilder来实现
fun <T> GlideRequest<T>.roundCorners(cornerRadius: Int) =
apply(RequestOptions().transform(RoundedCorners(cornerRadius)))
并使用as;
GlideApp.with(context)
.load(url)
.roundCorners(context.resources.getDimension(R.dimen.radius_in_dp).toInt())
.into(imgView)
为什么不在draw()中进行剪辑?
以下是我的解决方案:
用剪切扩展RelativeLayout 将ImageView(或其他视图)放入布局中:
代码:
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;
}
}
}
对我来说,下面的解决方案似乎是最优雅的:
ImageView roundedImageView = new ImageView (getContext());
roundedImageView.setClipToOutline(true);
Bitmap bitmap = AppUtil.decodeSampledBitmapFromResource(new File(valueListItemsView.getImagePath()), width, height);
roundedImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
roundedImageView.setImageBitmap(bitmap);
roundedImageView.setBackgroundResource(R.drawable.rounded_corner);
而可绘制的rounded_corner.xml的代码是:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/colorAccent" />
<corners android:radius="24dp" />
</shape>
我的ImageView圆角小部件的实现,(下||上)大小图像到所需的尺寸。它利用了CaspNZ的代码形式。
public class ImageViewRounded extends ImageView {
public ImageViewRounded(Context context) {
super(context);
}
public ImageViewRounded(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ImageViewRounded(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
BitmapDrawable drawable = (BitmapDrawable) getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap fullSizeBitmap = drawable.getBitmap();
int scaledWidth = getMeasuredWidth();
int scaledHeight = getMeasuredHeight();
Bitmap mScaledBitmap;
if (scaledWidth == fullSizeBitmap.getWidth() && scaledHeight == fullSizeBitmap.getHeight()) {
mScaledBitmap = fullSizeBitmap;
} else {
mScaledBitmap = Bitmap.createScaledBitmap(fullSizeBitmap, scaledWidth, scaledHeight, true /* filter */);
}
Bitmap roundBitmap = ImageUtilities.getRoundedCornerBitmap(getContext(), mScaledBitmap, 5, scaledWidth, scaledHeight,
false, false, false, false);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
}
在API 21的View类中添加了对圆形形状的剪切。
只要这样做:
创建一个可绘制的圆形形状,就像这样:
res - drawable round_outline xml。
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="10dp" />
...
</shape>
设置drawable作为ImageView的背景: android:背景= " @drawable / round_outline” 根据这个文档,那么你所需要做的就是添加android:clipToOutline="true"
不幸的是,有一个错误,无法识别该XML属性。幸运的是,我们仍然可以在Java中设置剪辑:
在你的活动或片段中:
下面是它的样子:
注意:
此方法适用于任何可绘制的形状(不仅仅是圆角)。它会剪辑ImageView到你在Drawable xml中定义的任何形状轮廓。
关于ImageViews的特别说明
setClipToOutline()仅在视图的背景设置为可绘制的形状时才有效。如果此背景形状存在,视图将形状的轮廓作为剪切和阴影目的的边界。
这意味着,如果你想使用setClipToOutline()圆角的ImageView,你的图像必须设置使用android:src而不是android:background(因为背景必须设置为您的圆角形状)。如果你必须使用背景来设置你的图像而不是src,你可以使用这个解决方案:
创建一个布局,并将其背景设置为可绘制的形状 将布局包装在ImageView周围(没有填充) ImageView(包括布局中的任何其他内容)现在将以圆角布局形状显示。