在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?
请注意,从2021年起,只需使用ShapeableImageView
在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?
请注意,从2021年起,只需使用ShapeableImageView
当前回答
我使用路径在图像画布上只画角。(我需要没有位图内存分配的解决方案)
@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,使用滑动,你可以使用这个方法应用圆角。
首先在你的gradle里写上,
compile 'com.github.bumptech.glide:glide:3.7.0'
对于有圆角的图像,
public void loadImageWithCorners(String url, ImageView view) {
Glide.with(context)
.load(url)
.asBitmap()
.centerCrop()
.placeholder(R.color.gray)
.error(R.color.gray)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(new BitmapImageViewTarget(view) {
@Override
protected void setResource(Bitmap resource) {
RoundedBitmapDrawable circularBitmapDrawable =
RoundedBitmapDrawableFactory.create(context.getResources(), resource);
circularBitmapDrawable.setCornerRadius(32.0f); // radius for corners
view.setImageDrawable(circularBitmapDrawable);
}
});
}
调用方法:
loadImageWithCorners("your url","your imageview");
有一个很酷的库可以让你塑造imageviews。
这里有一个例子:
<com.github.siyamed.shapeimageview.mask.PorterShapeImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:siShape="@drawable/shape_rounded_rectangle"
android:src="@drawable/neo"
app:siSquare="true"/>
形状定义:
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
<corners
android:topLeftRadius="18dp"
android:topRightRadius="18dp"
android:bottomLeftRadius="18dp"
android:bottomRightRadius="18dp" />
<solid android:color="@color/black" />
</shape>
结果:
在支持库的v21中,现在有了一个解决方案:它被称为RoundedBitmapDrawable。
它基本上就像一个普通的Drawable,除了你给它一个角半径的剪辑:
setCornerRadius(float cornerRadius)
所以,从Bitmap src和一个目标ImageView开始,它看起来像这样:
RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(res, src);
dr.setCornerRadius(cornerRadius);
imageView.setImageDrawable(dr);
下面的代码创建一个圆角矩形布局对象,该对象围绕放置在其中的任何子对象绘制圆角矩形。它还演示了如何在不使用布局xml文件的情况下以编程方式创建视图和布局。
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);
}
}
RoundedRectangle布局对象的类定义如下:
/**
* 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;
}
}
这不是确切的答案,但它是一个类似的解决方案。它可能会帮助那些和我有同样遭遇的人。
我的图像是一个应用程序logo,它的背景是透明的,我正在应用XML渐变作为图像背景。我在imageView中添加了必要的padding/margin,然后添加了这个作为我的背景:
<?xml version="1.0" encoding="utf-8"?>
<!-- This file defines the gradient used on the background of the main activity. -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:type="linear"
android:startColor="@color/app_color_light_background"
android:endColor="@color/app_color_disabled"
android:angle="90" />
<!-- Round the top corners. -->
<corners
android:topLeftRadius="@dimen/radius_small"
android:topRightRadius="@dimen/radius_small" />
</shape>
</item>
</selector>