在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?
请注意,从2021年起,只需使用ShapeableImageView
在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?
请注意,从2021年起,只需使用ShapeableImageView
当前回答
通过使用下面的代码,您可以改变顶部角半径
val image = findViewById<ImageView>(R.id.image)
val curveRadius = 20F
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
image.outlineProvider = object : ViewOutlineProvider() {
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun getOutline(view: View?, outline: Outline?) {
outline?.setRoundRect(0, 0, view!!.width, (view.height+curveRadius).toInt(), curveRadius)
}
}
image.clipToOutline = true
}
其他回答
这里使用ImageLoader
创建DisplayImageOptions:
DisplayImageOptions options = new DisplayImageOptions.Builder()
// this will make circle, pass the width of image
.displayer(new RoundedBitmapDisplayer(getResources().getDimensionPixelSize(R.dimen.image_dimen_menu)))
.cacheOnDisc(true)
.build();
imageLoader.displayImage(url_for_image,ImageView,options);
或者你也可以从Square上使用毕加索图书馆。
Picasso.with(mContext)
.load(com.app.utility.Constants.BASE_URL+b.image)
.placeholder(R.drawable.profile)
.error(R.drawable.profile)
.transform(new RoundedTransformation(50, 4))
.resizeDimen(R.dimen.list_detail_image_size, R.dimen.list_detail_image_size)
.centerCrop()
.into(v.im_user);
你可以在这里下载RoundedTransformation文件 在这里
为什么不在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;
}
}
}
这种纯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>
/**
* Background Async task to load user profile picture from url
*/
private class LoadProfileImage extends AsyncTask<String, Void, RoundedBitmapDrawable> {
ImageView profileImageView;
public LoadProfileImage(ImageView profileImageView) {
this.profileImageView = profileImageView;
}
protected RoundedBitmapDrawable doInBackground(String... urls) {
String photoUrl = urls[0];
RoundedBitmapDrawable profileRoundedDrawable = null;
try {
InputStream inputStream = new java.net.URL(photoUrl).openStream();
Resources res = getResources();
profileRoundedDrawable = RoundedBitmapDrawableFactory.create(res, inputStream);
profileRoundedDrawable.setCircular(true);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return profileRoundedDrawable;
}
protected void onPostExecute(RoundedBitmapDrawable result) {
profileImageView.setImageDrawable(result);
}
}
让你的ImageView像这样:
<com.example..CircularImageView
android:id="@+id/profile_image_round_corner"
android:layout_width="80dp"
android:layout_height="80dp"
android:scaleType="fitCenter"
android:padding="2dp"
android:background="@null"
android:adjustViewBounds="true"
android:layout_centerInParent="true"
android:src="@drawable/dummy"
/>
并创建一个类:
package com.example;
import java.util.Formatter.BigDecimalLayoutForm;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
public class CircularImageView extends ImageView {
public CircularImageView(Context context) {
super(context);
}
public CircularImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getRoundBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
public static Bitmap getRoundBitmap(Bitmap bmp, int radius) {
Bitmap sBmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
float factor = smallest / radius;
sBmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false);
} else {
sBmp = bmp;
}
Bitmap output = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, radius, radius);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(radius / 2 + 0.7f,
radius / 2 + 0.7f, radius / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sBmp, rect, rect, paint);
return output;
}
}