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


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


当前回答

尝试材质组件库并使用ShapeableImageView。 大概是这样的:

Java:

imageView=new ShapeableImageView(context);
imageView.setShapeAppearanceModel(
        imageView.getShapeAppearanceModel()
                 .toBuilder()
                 .setAllCornerSizes(20)
                 .build());

芬兰湾的科特林:

val imageView = ShapeableImageView(context)
imageView.setShapeAppearanceModel(
        imageView.getShapeAppearanceModel()
                 .toBuilder()
                 .setAllCornerSizes(20f)
                 .build())

其他回答

为什么不在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;
        }
    }

}

如果你们中有人面临这个问题

大多数情况下,你使用的是Android Studio。由于图像大小的调整和所有在Android工作室,你可能会遇到这个问题。解决这个问题的一个简单方法是减小drawCircle()中的圆的半径。在我的情况下,我使用这个修复

使用画布。drawCircle(100,100,90, paint);而不是帆布。drawCircle(100,100,100, paint);这绝对能解决你的问题。

下面是最终编辑的代码:-

  public class Profile extends ActionBarActivity {


    TextView username;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.profile);


        username= (TextView) findViewById(R.id.txt);

        String recievedusername=getIntent().getExtras().getString("toname");
        username.setText(recievedusername);


        Bitmap bm = BitmapFactory.decodeResource(getResources(),
                R.mipmap.gomez);

        Bitmap resizedBitmap = Bitmap.createScaledBitmap(bm, 200,200, false);
        Bitmap conv_bm=getCircleBitmap(resizedBitmap,100);
        // set circle bitmap
        ImageView mImage = (ImageView) findViewById(R.id.profile_image);
        mImage.setImageBitmap(conv_bm);
        // TODO Auto-generated method stub
    }
    private Bitmap getCircleBitmap(Bitmap bitmap , int pixels) {
        final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(output);
        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(),bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawCircle(100,100, 90, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        bitmap.recycle();
        return output;
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_apploud, menu);
        return super.onCreateOptionsMenu(menu);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_addnew) {
            Intent i;
            i=new Intent(Profile.this,ApplaudSomeone.class);
            startActivity(i);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

相当多的答案!

我遵循了一些人也建议的这个例子:http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

然而,我需要的是一个透明图像后面的彩色圆圈。对于任何有兴趣做同样事情的人…

1)设置FrameLayout的宽度和高度-在我的情况下,图像的大小(50dp)。 2)将带有src = "@drawable/…"的ImageView放在带有图像的ImageView之上。给它一个id,在我的例子中,我叫它iconShape 3) Drawable mask.xml应该是纯色的#ffffffff 4)如果你想在你的代码中动态地改变圆圈的颜色,可以这样做

ImageView iv2 = (ImageView) v.findViewById(R.id.iconShape);
Drawable shape = getResources().getDrawable(R.drawable.mask);
shape.setColorFilter(Color.BLUE, Mode.MULTIPLY);
iv2.setImageDrawable(shape);

我使用路径在图像画布上只画角。(我需要没有位图内存分配的解决方案)

@Override
protected void onDraw(final Canvas canvas) {
    super.onDraw(canvas);

    if (!hasRoundedCorners()) return;

    mPaint.setStyle(Paint.Style.FILL);
    mPaint.setStrokeWidth(0);

    Path path = new Path();
    path.setFillType(Path.FillType.INVERSE_WINDING);
    path.addRoundRect(new RectF(0, 0, getWidth(), getHeight()), mRadius, mRadius, Path.Direction.CCW);
    canvas.drawPath(path, mPaint);
}

注意,你不应该在onDraw方法中分配任何新对象。此代码是概念验证,不应该在产品代码中这样使用

看到更多: https://medium.com/@przemek.materna/rounded-image-view-no-bitmap-reallocation-11a8b163484d

对我来说,下面的解决方案似乎是最优雅的:

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>