如何制作带有圆角的ImageView?
在 Android 中,ImageView 默认是一个矩形。如何在 ImageView 中使其成为圆角矩形(将位图的所有 4 个角剪成圆角矩形)?
请注意,从 2021 年起,只需使用 ShapeableImageView
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
这响应相当晚了,但对于正在寻找此内容的其他人,您可以执行以下代码来手动圆化图像的角。
http://www.ruibm.com/?p=184
这不是我的代码,但我已经使用过它并且效果非常好。我将它用作 ImageHelper 类中的助手,并对其进行了一些扩展以传递给定图像所需的羽化量。
最终代码如下所示:
This is pretty late in response, but for anyone else that is looking for this, you can do the following code to manually round the corners of your images.
http://www.ruibm.com/?p=184
This isn't my code, but I've used it and it's works wonderfully. I used it as a helper within an ImageHelper class and extended it just a bit to pass in the amount of feathering I need for a given image.
Final code looks like this:
另一种简单的方法是使用带有圆角半径的 CardView 和内部的 ImageView:
Another easy way is to use a CardView with the corner radius and an ImageView inside:
剪切到圆形形状已添加到
View
类。
只需执行以下操作:
res/drawable/round_outline.xml
android:background="@drawable/round_outline"
android:clipToOutline="true"
不幸的是,有 一个 bug 并且 XML 属性无法识别。幸运的是,我们仍然可以在 Java 中设置剪切:
ImageView.setClipToOutline(true)
如下所示:
注意:
此方法适用于任何可绘制形状(不仅仅是圆形) 。它将把 ImageView 裁剪为您在 Drawable xml 中定义的任何形状轮廓。
关于 ImageView 的特别说明
setClipToOutline()
仅当 View 的背景设置为可绘制形状时才有效。如果此背景形状存在,View 会将该形状的轮廓视为用于剪切和阴影目的的边框。这意味着,如果您想使用
setClipToOutline()
来圆化 ImageView 上的角,则必须使用android:src
而不是android:background 设置图像
(因为背景必须设置为圆形)。如果您必须使用背景而不是 src 来设置图像,则可以使用以下解决方法:Clipping to rounded shapes was added to the
View
class in API 21.Just do this:
res/drawable/round_outline.xml
android:background="@drawable/round_outline"
android:clipToOutline="true"
Unfortunately, there's a bug and that XML attribute is not recognized. Luckily, we can still set up clipping in Java:
ImageView.setClipToOutline(true)
Here's what it will look like:
Note:
This method works for any drawable shape (not just rounded). It will clip the ImageView to whatever shape outline you've defined in your Drawable xml.
Special note about ImageViews
setClipToOutline()
only works when the View's background is set to a shape drawable. If this background shape exists, View treats the shape's outline as the borders for clipping and shadowing purposes.This means, if you want to use
setClipToOutline()
to round the corners on an ImageView, your image must be set usingandroid:src
instead ofandroid:background
(since background must be set to your rounded shape). If you MUST use background to set your image instead of src, you can use this workaround:从
1.2.0-alpha03
开始“noreferrer">材质组件库有新的ShapeableImageView
。使用以下内容
您可以在
themes.xml
中:或以编程方式使用:
使用jetpack compose,您可以应用
剪辑
修饰符
使用RoundedCornerShape
:Starting with the version
1.2.0-alpha03
of the Material Components Library there is the newShapeableImageView
.You can use something like:
with in your
themes.xml
:Or programmatically:
With jetpack compose you can apply a
clip
Modifier
using aRoundedCornerShape
:虽然上述答案有效,但 Romain Guy(核心 Android 开发人员)显示 一种更好的方法,该方法通过使用着色器而不创建位图副本来使用更少的内存。该功能的一般要点如下:
与其他方法相比,此方法的优点在于:
我创建了一个 RoundedImageView< /a> 基于此代码,将该逻辑包装到 ImageView 中,并添加适当的 ScaleType 支持和可选的圆形边框。
While the above answer works, Romain Guy (a core Android developer) shows a better method in his blog which uses less memory by using a shader not creating a copy of the bitmap. The general gist of the functionality is here:
The advantages of this over other methods is that it:
I've created a RoundedImageView based off this code that wraps this logic into an ImageView and adds proper
ScaleType
support and an optional rounded border.在支持库的 v21 中,现在有一个解决方案:它称为 RoundedBitmapDrawable。
它基本上就像一个普通的 Drawable,除了你给它一个用于剪切的角半径:
因此,从
Bitmap src
和目标ImageView
开始,它看起来像这样:In the v21 of the Support library there is now a solution to this: it's called RoundedBitmapDrawable.
It's basically just like a normal Drawable except you give it a corner radius for the clipping with:
So, starting with
Bitmap src
and a targetImageView
, it would look something like this:快速 xml 解决方案 -
您可以在 CardView 上设置所需的宽度、高度和半径,在 ImageView 上设置scaleType。
对于 AndroidX,请使用
A quick xml solution -
You can set your desired width, height and radius on CardView and scaleType on ImageView.
With AndroidX, use
<androidx.cardview.widget.CardView>
我已经通过自定义 ImageView 完成:
如何使用:
输出:
希望这会对您有所帮助。
I have done by Custom ImageView:
How to use:
Output:
Hope this would help you.
我发现这两种方法对于提出可行的解决方案都非常有帮助。这是我的复合版本,它与像素无关,并允许您有一些方角,其余角具有相同的半径(这是通常的用例)。
感谢上面的两个解决方案:
此外,我覆盖了 ImageView 将其放入,以便我可以在 xml 中定义它。
您可能想在此处添加 super 调用的一些逻辑,但我已对其进行了评论,因为它对我的情况没有帮助。
希望这有帮助!
I found that both methods were very helpful in coming up with a working solution. Here is my composite version, that is pixel independent and allows you to have some square corners with the rest of the corners having the same radius (which is the usual use case).
With thanks to both of the solutions above:
Also, I overrode ImageView to put this in so I could define it in xml.
You may want to add in some of the logic that the super call makes here, but I've commented it as it's not helpful in my case.
Hope this helps!
使用
ImageLoader
的圆形图像此处创建
DisplayImageOptions
:或者您可以使用 Square 的
Picasso
库。您可以在此处下载 RoundedTransformation 文件
此处
Rounded image Using
ImageLoader
hereCreate
DisplayImageOptions
:Or you can user
Picasso
Library from Square.you can download RoundedTransformation file here
here
由于所有的答案对我来说似乎太复杂了,只是为了圆角,我想到了另一个我认为值得分享的解决方案,只是使用 XML,以防图像周围有一些空间:
创建一个带有透明内容的边框形状,如下所示:
然后在RelativeLayout中,您可以首先放置图像,然后将另一个ImageView放置在形状上方的同一位置。封面形状的尺寸应大于边框宽度。请小心采用较大的角半径,因为定义了外半径,但内半径覆盖了图像。
希望它也能帮助别人。
根据 CQM 请求编辑相对布局示例:
As all the answers seemed too complicated for me just for round corners I thought and came to another solution which I think is worth to share, just with XML in case you have some space around the image:
Create a bordered shape with transparent content like this:
Then in a RelativeLayout you can first place your image and then in the same location above the shape with another ImageView. The cover-shape should be larger in size by the amount of the border width. Be careful to take a larger corner radius as the outer radius is defined but the inner radius is what covers your image.
Hope it helps somebody, too.
Edit as per CQM request the relative layout example:
它可以通过使用
ShapeAppearanceOverlay
的ShapeableImageView
来完成:其中样式
ShapeAppearanceOverlay.Avatar
位于res/values/styles.xml< /code>:
这只需要设置相等的
layout_height
和layout_width
,否则将是一个没有圆圈的药丸。It can be done with a
ShapeableImageView
using aShapeAppearanceOverlay
:Where style
ShapeAppearanceOverlay.Avatar
resides inres/values/styles.xml
:This just need equal
layout_height
andlayout_width
set, else with will be a pill an no circle.我使用圆角小部件实现 ImageView,将图像尺寸(向下||向上)调整到所需的尺寸。它使用 CaspNZ 形式的代码。
My implementation of ImageView with rounded corners widget, that (down||up)sizes image to required dimensions. It utilizes code form CaspNZ.
截至最近,还有另一种方法 - 使用 Glide 的生成 API。它需要一些初始工作,但随后为您提供了 Glide 的所有功能,并且可以灵活地执行任何操作,因为您编写了实际代码,所以我认为从长远来看这是一个很好的解决方案。另外,用法非常简单和整洁。
首先,设置 Glide 版本 4+:
然后创建 Glid 的应用程序模块类来触发注释处理:
然后创建真正完成这项工作的滑翔扩展。您可以自定义它来执行您想要的任何操作:
添加这些文件后,构建您的项目。
然后在您的代码中使用它,如下所示:
As of recently, there is another way - using Glide's Generated API. It takes some initial work but then gives you all the power of Glide with the flexibility to do anything because you writhe the actual code so I think it's a good solution for the long run. Plus, the usage is very simple and neat.
First, setup Glide version 4+:
Then create Glid's app module class to trigger the annotation processing:
Then create the Glide extension which actually does the work. You can customize it to do whatever you want:
After adding these files, build your project.
Then use it in your code like this:
有一个很酷的库可以让你塑造图像视图。
下面是一个示例:
形状定义:
结果:
There is a cool library that allows you to shape imageviews.
Here is an example:
Shape definition:
Result:
2023 年 11 月
尝试材质组件库并使用
ShapeableImageView
。像这样的:
Java:
Kotlin:
Jetpack Compose:
X
是一个数值,一个 Single用于创建形状的值,其大小与所有四个角的大小相同。您还可以为每个角使用四个不同的值。Nov 2023
Try the Material Components Library and use the
ShapeableImageView
.Somethig like this :
Java :
Kotlin :
Jetpack Compose :
X
is a numeric value, a Single value used to create the shape with the same size applied for all four corners. Also you can use four different values for each corner.这是一个覆盖 imageView 的简单示例,您也可以在布局设计器中使用它进行预览。
这是为了快速解决。半径用于所有角,并且基于位图宽度的百分比。
我刚刚重写了 setImageDrawable 并使用了支持 v4 方法来绘制圆角位图。
用法:
使用 imageView 和自定义 imageView 进行预览:
Here is a simple example overriding imageView, you can then also use it in layout designer to preview.
This is for fast solution. Radius is used on all corners and is based of percentage of bitmap width.
I just overrided
setImageDrawable
and used support v4 method for rounded bitmap drawable.Usage:
Preview with imageView and custom imageView:
Kotlin
要使
ImageView
成为圆形,我们可以更改cornerRadius
:Kotlin
To make
ImageView
Circular we can changecornerRadius
with:将形状应用到您的
imageView
,如下所示:这可能对您的朋友有帮助。
Apply a shape to your
imageView
as below:it may be helpful to you friend.
您应该扩展
ImageView
并绘制您自己的圆角矩形。如果您想要图像周围有一个框架,您还可以将圆形框架叠加在布局中图像视图的顶部。
[编辑]将框架叠加到原始图像上,例如使用
FrameLayout
。FrameLayout
的第一个元素将是您想要显示为圆角的图像。然后添加另一个带有框架的ImageView
。第二个ImageView
将显示在原始ImageView
之上,因此 Android 会将其内容绘制在原始ImageView
之上。You should extend
ImageView
and draw your own rounded rectangle.If you want a frame around the image you could also superimpose the rounded frame on top of the image view in the layout.
[edit]Superimpose the frame on to op the original image, by using a
FrameLayout
for example. The first element of theFrameLayout
will be the image you want to diplay rounded. Then add anotherImageView
with the frame. The secondImageView
will be displayed on top of the originalImageView
and thus Android will draw it's contents above the orignalImageView
.支持上面的乔治·沃尔特斯二世,我只是接受了他的答案并将其扩展了一点以支持以不同的方式圆化各个角。这可以进一步优化(一些目标矩形重叠),但不是很多。
我知道这个线程有点旧,但它是 Google 上关于如何在 Android 上圆化 ImageViews 角的查询的最佳结果之一。
Props to George Walters II above, I just took his answer and extended it a bit to support rounding individual corners differently. This could be optimized a bit further (some of the target rects overlap), but not a whole lot.
I know this thread is a bit old, but its one of the top results for queries on Google for how to round corners of ImageViews on Android.
罗曼·盖伊就在那里。
缩小版本如下。
Romain Guy is where it's at.
Minified version as follows.
为什么不在
draw()
中进行裁剪呢?这是我的解决方案:
代码:
Why not do clipping in
draw()
?Here is my solution:
Code:
这个纯 xml 解决方案对于我来说已经足够好了。 http:// /www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/
编辑
简而言之,答案如下:
在 /res/drawable 文件夹中,创建一个frame.xml 文件。在其中,我们定义了一个带有圆角和透明中心的简单矩形。
在布局文件中添加一个包含标准 ImageView 的 LinearLayout 以及一个嵌套的 FrameLayout。 FrameLayout 使用填充和自定义可绘制来提供圆角的错觉。
This pure xml solution was good enough in my case. http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/
EDIT
Here's the answer in a nutshell:
In the /res/drawable folder, create a frame.xml file. In it, we define a simple rectangle with rounded corners and a transparent center.
In your layout file you add a LinearLayout that contains a standard ImageView, as well as a nested FrameLayout. The FrameLayout uses padding and the custom drawable to give the illusion of rounded corners.
答案中提供的方法都不适合我。我发现如果你的android版本是5.0或更高版本,以下方法有效:
没有要定义的xml形状,上面的代码只为顶部创建角,普通方法不起作用。如果需要4个角为圆角,请
从setRoundRect中的bottom参数中 删除:您可以通过指定适合您需要的轮廓来进一步将形状扩展到任何其他形状。请查看以下链接:
Android 开发人员文档。
请注意,与 Android 中的任何度量一样,您通常必须“转换”来自 DP 的尺寸。在上面的示例中,假设您希望半径为 24
,例如,您稍后可能会在半径设置为“24”的可绘制对象中添加边框,并且您希望它匹配。因此,
然后
None of the methods provided in the answers worked for me. I found the following way works if your android version is 5.0 or above:
No xml shapes to be defined, and the code above create corners only for top, which normal methods won't work. If you need 4 corners to be rounded, remove:
From the parameter for bottom in setRoundRect. You can further expand the shape to any others by specifying outlines that suit your needs. Check out the following link:
Android Developer Documentation.
Note, as with any measure in Android, you have to "convert" the size typically from DP. In the example above, say you want the radius to be 24
For example you may be later adding a border in a drawable with the radius set as "24" and you wish it to match. Hence,
and then
下面创建一个圆角矩形布局对象,该对象在放置在其中的任何子对象周围绘制一个圆角矩形。它还演示了如何以编程方式创建视图和布局,而不使用布局 xml 文件。
RoundedRectangle 布局对象的类定义如下:
The following creates a rounded rectangle layout object that draws a rounded rectangle around any child objects that are placed in it. It also demonstrates how to create views and layouts programmatically without using the layout xml files.
The class for RoundedRectangle layout object is as defined here:
如果您正在使用 Glide 库,这会很有帮助:
If you are using Glide Library this would be helpful:
非常感谢第一个回答。这是修改后的版本,用于将矩形图像转换为方形图像(和圆形),并且填充颜色作为参数传递。
Thanks a lot to first answer. Here is modified version to convert a rectangular image into a square one (and rounded) and fill color is being passed as parameter.
如果您的图像位于互联网上,最好的方法是使用 glide 和 RoundedBitmapDrawableFactory (来自 API 21 - 但在支持库中可用),如下所示:
if your image is on internet the best way is using glide and
RoundedBitmapDrawableFactory
(from API 21 - but available in support library) like so:回答此处重定向的问题:
“如何在 Android 中创建圆形 ImageView?”
Answer for the question that is redirected here:
"How to create a circular ImageView in Android?"