mic*_*ael 537 android rounded-corners imageview android-image android-imageview
在Android中,默认情况下ImageView是一个矩形.如何在ImageView中将其设置为圆角矩形(将我的Bitmap的所有4个角切掉为圆角矩形)?
Geo*_* II 538
这已经很晚了,但对于其他正在寻找此问题的人来说,您可以执行以下代码来手动围绕图像的角落.
这不是我的代码,但我已经使用过了,它的功能非常好.我在ImageHelper类中使用它作为帮助器,并将它扩展了一点,以传递给定图像所需的羽化量.
最终代码如下所示:
package com.company.app.utils;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Bitmap.Config;
import android.graphics.PorterDuff.Mode;
public class ImageHelper {
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
.getHeight(), Config.ARGB_8888);
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);
final float roundPx = pixels;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
}
Run Code Online (Sandbox Code Playgroud)
希望这有助于某人!
vin*_*3m1 206
虽然上述答案有效,但Romain Guy(核心Android开发人员)在他的博客中展示了一种更好的方法,通过使用着色器而不创建位图副本来减少内存.功能的一般要点是:
BitmapShader shader;
shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);
RectF rect = new RectF(0.0f, 0.0f, width, height);
// rect contains the bounds of the shape
// radius is the radius in pixels of the rounded corners
// paint contains the shader that will texture the shape
canvas.drawRoundRect(rect, radius, radius, paint);
Run Code Online (Sandbox Code Playgroud)
与其他方法相比,它的优点是:
我已经创建了一个基于此代码的RoundedImageView,它将此逻辑包装到ImageView中,并添加适当的ScaleType支持和可选的圆形边框.
Tar*_*ych 168
另一种简单的方法是使用带角半径的CardView和内部的ImageView:
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardCornerRadius="8dp"
android:layout_margin="5dp"
android:elevation="10dp">
<ImageView
android:id="@+id/roundedImageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/image"
android:background="@color/white"
android:scaleType="centerCrop"
/>
</android.support.v7.widget.CardView>
Run Code Online (Sandbox Code Playgroud)
tyc*_*czj 125
在支持库的v21中,现在有一个解决方案:它叫做RoundedBitmapDrawable.
它基本上就像普通的Drawable一样,除非你给它一个角落半径用于裁剪:
setCornerRadius(float cornerRadius)
Run Code Online (Sandbox Code Playgroud)
所以,从Bitmap src和目标开始ImageView,它看起来像这样:
RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(res, src);
dr.setCornerRadius(cornerRadius);
imageView.setImageDrawable(dr);
Run Code Online (Sandbox Code Playgroud)
hun*_*ost 119
View在API 21中向类中添加了剪切为圆形的形状.
这样做:
RES /抽拉/ round_outline.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="10dp" />
...
</shape>
Run Code Online (Sandbox Code Playgroud)
android:background="@drawable/round_outline"android:clipToOutline="true"不幸的是,有一个错误,并且无法识别XML属性.幸运的是,我们仍然可以在Java中设置剪辑:
ImageView.setClipToOutline(true)这是它的样子:

注意:
此方法适用于任何可绘制的形状(不仅仅是圆形).它会将ImageView剪切为您在Drawable xml中定义的任何形状轮廓.
关于ImageViews的特别说明
setClipToOutline()仅在视图的背景设置为可绘制形状时才有效.如果存在此背景形状,View会将形状的轮廓视为用于剪切和阴影的边框.
这意味着,如果要用于setClipToOutline()对ImageView上的角进行圆角处理,则必须使用android:src而不是android:background(因为背景必须设置为圆角形状)来设置图像.如果你必须使用背景来设置你的图像而不是src,你可以使用这个解决方法:
Gab*_*tti 118
与版本开始1.2.0-alpha03的的的材料构件库有新的ShapeableImageView。
您可以使用以下内容:
<com.google.android.material.imageview.ShapeableImageView
...
app:shapeAppearanceOverlay="@style/roundedImageView"
app:srcCompat="@drawable/ic_image" />
Run Code Online (Sandbox Code Playgroud)
和:
<style name="roundedImageView" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">8dp</item>
</style>
Run Code Online (Sandbox Code Playgroud)
或以编程方式:
float radius = getResources().getDimension(R.dimen.default_corner_radius);
imageView.setShapeAppearanceModel(imageView.getShapeAppearanceModel()
.toBuilder()
.setAllCorners(CornerFamily.ROUNDED,radius)
.build());
Run Code Online (Sandbox Code Playgroud)
使用jetpack compose, 1.0.x您可以使用 a 应用:clip ModifierRoundedCornerShape
Image(
painter = painterResource(R.drawable.xxxx),
contentDescription = "xxxx",
contentScale = ContentScale.Crop,
modifier = Modifier
.size(64.dp)
.clip(RoundedCornerShape(8.dp))
)
Run Code Online (Sandbox Code Playgroud)
Hir*_*tel 65
我已经通过Custom ImageView完成了:
public class RoundRectCornerImageView extends ImageView {
private float radius = 18.0f;
private Path path;
private RectF rect;
public RoundRectCornerImageView(Context context) {
super(context);
init();
}
public RoundRectCornerImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public RoundRectCornerImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
path = new Path();
}
@Override
protected void onDraw(Canvas canvas) {
rect = new RectF(0, 0, this.getWidth(), this.getHeight());
path.addRoundRect(rect, radius, radius, Path.Direction.CW);
canvas.clipPath(path);
super.onDraw(canvas);
}
}
Run Code Online (Sandbox Code Playgroud)
如何使用:
<com.mypackage.RoundRectCornerImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/image"
android:scaleType="fitXY" />
Run Code Online (Sandbox Code Playgroud)
输出:
希望这会对你有所帮助.
Cas*_*mer 56
我发现这两种方法都非常有助于提出一个有效的解决方案.这是我的复合版本,它是像素独立的,允许你有一些方角,其余的角具有相同的半径(这是通常的用例).感谢上述两种解决方案:
public static Bitmap getRoundedCornerBitmap(Context context, Bitmap input, int pixels , int w , int h , boolean squareTL, boolean squareTR, boolean squareBL, boolean squareBR ) {
Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final float densityMultiplier = context.getResources().getDisplayMetrics().density;
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, w, h);
final RectF rectF = new RectF(rect);
//make sure that our rounded corner is scaled appropriately
final float roundPx = pixels*densityMultiplier;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
//draw rectangles over the corners we want to be square
if (squareTL ){
canvas.drawRect(0, h/2, w/2, h, paint);
}
if (squareTR ){
canvas.drawRect(w/2, h/2, w, h, paint);
}
if (squareBL ){
canvas.drawRect(0, 0, w/2, h/2, paint);
}
if (squareBR ){
canvas.drawRect(w/2, 0, w, h/2, paint);
}
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(input, 0,0, paint);
return output;
}
Run Code Online (Sandbox Code Playgroud)
另外,我重写了ImageView,因此我可以在xml中定义它.你可能想要添加超级调用在这里制作的一些逻辑,但我已经对它进行了评论,因为它对我的情况没有帮助.
@Override
protected void onDraw(Canvas canvas) {
//super.onDraw(canvas);
Drawable drawable = getDrawable();
Bitmap b = ((BitmapDrawable)drawable).getBitmap() ;
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = CropImageView.getRoundedCornerBitmap( getContext(), bitmap,10 , w, h , true, false,true, false);
canvas.drawBitmap(roundBitmap, 0,0 , null);
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
sha*_*esh 46
圆角图像使用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);
Run Code Online (Sandbox Code Playgroud)
或者您可以Picasso从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);
Run Code Online (Sandbox Code Playgroud)
你可以在这里下载RoundedTransformation文件
小智 43
快速的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>
Run Code Online (Sandbox Code Playgroud)
您可以在CardView上设置所需的宽度,高度和半径,并在ImageView上设置scaleType。
Chr*_*ian 26
由于所有的答案对于我来说似乎太复杂了,我认为并且来到另一个我认为值得分享的解决方案,只是在XML中以防你在图像周围有一些空间:
创建一个带有透明内容的边框形状,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="30dp" />
<stroke
android:color="#ffffffff"
android:width="10dp" />
</shape>
Run Code Online (Sandbox Code Playgroud)
然后在RelativeLayout中,您可以先放置图像,然后使用另一个ImageView放置在形状上方的相同位置.盖子形状的尺寸应该大于边界宽度.在定义外半径时要小心采用较大的圆角半径,但内半径是覆盖图像的半径.
希望它也可以帮助某人.
根据CQM请求编辑相对布局示例:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/imageToShow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/imgCorners"
android:layout_alignLeft="@+id/imgCorners"
android:layout_alignRight="@+id/imgCorners"
android:layout_alignTop="@+id/imgCorners"
android:background="#ffffff"
android:contentDescription="@string/desc"
android:padding="5dp"
android:scaleType="centerCrop" />
<ImageView
android:id="@+id/imgCorners"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@string/desc"
android:src="@drawable/corners_white" />
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
Mar*_*ler 23
可以通过ShapeableImageView使用 a来完成ShapeAppearanceOverlay:
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/avatar"
android:layout_width="64dp"
android:layout_height="64dp"
android:padding="4dp"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Avatar"/>
Run Code Online (Sandbox Code Playgroud)
风格ShapeAppearanceOverlay.Avatar所在res/values/styles.xml:
<style name="ShapeAppearanceOverlay.Avatar" parent="ShapeAppearance.MaterialComponents.SmallComponent">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>
</style>
Run Code Online (Sandbox Code Playgroud)
这只需要相等layout_height并layout_width设置,否则将是一个没有圆圈的药丸。
Dam*_*jan 14
我实现了带圆角小部件的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);
}
}
Run Code Online (Sandbox Code Playgroud)
ucM*_*dia 13
2023 年 11 月
尝试材质组件库并使用ShapeableImageView.
像这样的东西:
爪哇:
imageView=new ShapeableImageView(context);
imageView.setShapeAppearanceModel(
imageView.getShapeAppearanceModel()
.toBuilder()
.setAllCornerSizes(20)
.build());
Run Code Online (Sandbox Code Playgroud)
科特林:
val imageView = ShapeableImageView(context)
imageView.setShapeAppearanceModel(
imageView.getShapeAppearanceModel()
.toBuilder()
.setAllCornerSizes(20f)
.build())
Run Code Online (Sandbox Code Playgroud)
喷气背包组成:
Image(
modifier = Modifier.clip(RoundedCornerShape(X)),
painter = painterResource(id = R.drawable.photo),
contentDescription = null)
Run Code Online (Sandbox Code Playgroud)
X是一个数值,一个单一值,用于创建四个角应用相同大小的形状。您还可以为每个角使用四个不同的值。
x : Int = 50 // Size in percents
x : Float = 25f // Size in pixels
x : Dp = 25.dp // Size in Dp
Run Code Online (Sandbox Code Playgroud)
Sir*_*lot 11
截至最近,还有另一种方法 - 使用Glide的Generated API.它需要一些初步的工作,但随后给你Glide的所有功能,可以灵活地做任何事情,因为你写了实际的代码,所以我认为从长远来看这是一个很好的解决方案.此外,使用非常简单和整洁.
首先,设置Glide版本4+:
implementation 'com.github.bumptech.glide:glide:4.6.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'
Run Code Online (Sandbox Code Playgroud)
然后创建Glid的app模块类来触发注释处理:
@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}
Run Code Online (Sandbox Code Playgroud)
然后创建实际完成工作的Glide扩展.您可以自定义它以执行任何操作:
@GlideExtension
public class MyGlideExtension {
private MyGlideExtension() {}
@NonNull
@GlideOption
public static RequestOptions roundedCorners(RequestOptions options, @NonNull Context context, int cornerRadius) {
int px = Math.round(cornerRadius * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
return options.transforms(new RoundedCorners(px));
}
}
Run Code Online (Sandbox Code Playgroud)
添加这些文件后,构建您的项目.
然后在你的代码中使用它,如下所示:
GlideApp.with(this)
.load(imageUrl)
.roundedCorners(getApplicationContext(), 5)
.into(imageView);
Run Code Online (Sandbox Code Playgroud)
科特林
import android.graphics.BitmapFactory
import android.os.Bundle
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory
import kotlinx.android.synthetic.main.activity_main.*
val bitmap = BitmapFactory.decodeResource(resources, R.drawable.myImage)
val rounded = RoundedBitmapDrawableFactory.create(resources, bitmap)
rounded.cornerRadius = 20f
profileImageView.setImageDrawable(rounded)
Run Code Online (Sandbox Code Playgroud)
为了使ImageView循环,我们可以改变cornerRadius:
rounded.isCircular = true
Run Code Online (Sandbox Code Playgroud)
有一个很酷的库,可以让你塑造形象视图.
这是一个例子:
<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"/>
Run Code Online (Sandbox Code Playgroud)
形状定义:
<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>
Run Code Online (Sandbox Code Playgroud)
结果:
这是一个覆盖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);
}
}
Run Code Online (Sandbox Code Playgroud)
这是快速解决方案。半径用于所有角,并且基于位图宽度的百分比。
我只是重写了setImageDrawable支持v4方法,并将其用于可绘制的圆形位图。
用法:
<com.example.widgets.RoundedImageView
android:layout_width="39dp"
android:layout_height="39dp"
android:src="@drawable/your_drawable" />
Run Code Online (Sandbox Code Playgroud)
使用imageView和自定义imageView进行预览:
您应该扩展ImageView并绘制自己的圆角矩形.
如果您想在图像周围使用框架,您还可以将圆形框架叠加在布局中的图像视图顶部.
[编辑]通过使用FrameLayout例如将帧叠加到原始图像上.第一个元素FrameLayout将是您想要四舍五入的图像.然后ImageView用框架添加另一个.第二个ImageView将显示在原始文件的顶部,ImageView因此Android将在orignal上方绘制它的内容ImageView.
小智 6
上面的乔治沃尔特斯二世的道具,我只是采取了他的答案并扩展了一点,以支持不同的圆角.这可以进一步优化(一些目标重叠),但不是很多.
我知道这个帖子有点陈旧,但它是谷歌查询如何在Android上绕过ImageViews的最佳结果之一.
/**
* Use this method to scale a bitmap and give it specific rounded corners.
* @param context Context object used to ascertain display density.
* @param bitmap The original bitmap that will be scaled and have rounded corners applied to it.
* @param upperLeft Corner radius for upper left.
* @param upperRight Corner radius for upper right.
* @param lowerRight Corner radius for lower right.
* @param lowerLeft Corner radius for lower left.
* @param endWidth Width to which to scale original bitmap.
* @param endHeight Height to which to scale original bitmap.
* @return Scaled bitmap with rounded corners.
*/
public static Bitmap getRoundedCornerBitmap(Context context, Bitmap bitmap, float upperLeft,
float upperRight, float lowerRight, float lowerLeft, int endWidth,
int endHeight) {
float densityMultiplier = context.getResources().getDisplayMetrics().density;
// scale incoming bitmap to appropriate px size given arguments and display dpi
bitmap = Bitmap.createScaledBitmap(bitmap,
Math.round(endWidth * densityMultiplier),
Math.round(endHeight * densityMultiplier), true);
// create empty bitmap for drawing
Bitmap output = Bitmap.createBitmap(
Math.round(endWidth * densityMultiplier),
Math.round(endHeight * densityMultiplier), Config.ARGB_8888);
// get canvas for empty bitmap
Canvas canvas = new Canvas(output);
int width = canvas.getWidth();
int height = canvas.getHeight();
// scale the rounded corners appropriately given dpi
upperLeft *= densityMultiplier;
upperRight *= densityMultiplier;
lowerRight *= densityMultiplier;
lowerLeft *= densityMultiplier;
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
// fill the canvas with transparency
canvas.drawARGB(0, 0, 0, 0);
// draw the rounded corners around the image rect. clockwise, starting in upper left.
canvas.drawCircle(upperLeft, upperLeft, upperLeft, paint);
canvas.drawCircle(width - upperRight, upperRight, upperRight, paint);
canvas.drawCircle(width - lowerRight, height - lowerRight, lowerRight, paint);
canvas.drawCircle(lowerLeft, height - lowerLeft, lowerLeft, paint);
// fill in all the gaps between circles. clockwise, starting at top.
RectF rectT = new RectF(upperLeft, 0, width - upperRight, height / 2);
RectF rectR = new RectF(width / 2, upperRight, width, height - lowerRight);
RectF rectB = new RectF(lowerLeft, height / 2, width - lowerRight, height);
RectF rectL = new RectF(0, upperLeft, width / 2, height - lowerLeft);
canvas.drawRect(rectT, paint);
canvas.drawRect(rectR, paint);
canvas.drawRect(rectB, paint);
canvas.drawRect(rectL, paint);
// set up the rect for the image
Rect imageRect = new Rect(0, 0, width, height);
// set up paint object such that it only paints on Color.WHITE
paint.setXfermode(new AvoidXfermode(Color.WHITE, 255, AvoidXfermode.Mode.TARGET));
// draw resized bitmap onto imageRect in canvas, using paint as configured above
canvas.drawBitmap(bitmap, imageRect, imageRect, paint);
return output;
}
Run Code Online (Sandbox Code Playgroud)
小智 6
为什么不在draw()中剪裁?
这是我的解决方案:
码:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
Romain Guy就在这里.
缩小版如下.
Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.image)).getBitmap();
Bitmap bitmapRounded = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
Canvas canvas = new Canvas(bitmapRounded);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawRoundRect((new RectF(0.0f, 0.0f, bitmap.getWidth(), bitmap.getHeight())), 10, 10, paint);
imageView.setImageBitmap(bitmapRounded);
Run Code Online (Sandbox Code Playgroud)
在我的情况下,这个纯xml解决方案已经足够了.http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/
编辑
简而言之,这就是答案:
在/ 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>
Run Code Online (Sandbox Code Playgroud)
在布局文件中,添加包含标准ImageView的LinearLayout,以及嵌套的FrameLayout.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>
Run Code Online (Sandbox Code Playgroud)
答案中提供的任何方法都不适合我。如果您的 android 版本是 5.0 或更高版本,我发现以下方法有效:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
ViewOutlineProvider provider = new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
int curveRadius = 24;
outline.setRoundRect(0, 0, view.getWidth(), (view.getHeight()+curveRadius), curveRadius);
}
};
imageview.setOutlineProvider(provider);
imageview.setClipToOutline(true);
}
Run Code Online (Sandbox Code Playgroud)
没有要定义的 xml 形状,上面的代码只为顶部创建角,普通方法不起作用。如果您需要圆角 4 个角,请删除:
"+ curveRadius"
Run Code Online (Sandbox Code Playgroud)
从 setRoundRect 中的底部参数。您可以通过指定适合您需要的轮廓将形状进一步扩展为任何其他形状。查看以下链接:
请注意,与 Android 中的任何度量一样,您必须“转换”通常来自 DP 的大小。在上面的示例中,假设您希望半径为 24
int curveRadius = 24;
Run Code Online (Sandbox Code Playgroud)
例如,您可能稍后会在半径设置为“24”的 drawable 中添加边框,并且您希望它匹配。因此,
float desiredRadius = 24;
float radiusConverted = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
desiredRadius,
itemView.getContext().getResources().getDisplayMetrics());
Run Code Online (Sandbox Code Playgroud)
进而
int curveRadius = radiusConverted;
Run Code Online (Sandbox Code Playgroud)
下面创建一个圆角矩形布局对象,围绕放置在其中的任何子对象绘制一个圆角矩形.它还演示了如何在不使用布局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);
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
将形状应用于您的形状,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>
Run Code Online (Sandbox Code Playgroud)
这可能对您的朋友有帮助。
如果您正在使用 Glide 库,这会很有帮助:
Glide.with(getApplicationContext())
.load(image_url)
.asBitmap()
.centerCrop()
.into(new BitmapImageViewTarget(imageView) {
@Override
protected void setResource(Bitmap resource) {
RoundedBitmapDrawable circularBitmapDrawable =
RoundedBitmapDrawableFactory.create(getApplicationContext().getResources(), resource);
circularBitmapDrawable.setCornerRadius(dpToPx(10));
circularBitmapDrawable.setAntiAlias(true);
imageView.setImageDrawable(circularBitmapDrawable);
}
});
public int dpToPx(int dp) {
DisplayMetrics displayMetrics = getApplicationContext().getResources().getDisplayMetrics();
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
419537 次 |
| 最近记录: |