通过XML实现圆形ImageView

295

我想让我的ImageView中的任何图像都带有圆形边框。

我搜索了但没有找到有用的信息(任何我尝试的方法都不起作用)。

如何通过XML实现这一点: 创建一个具有特定src的ImageView并使其成为圆形边框?


如何在Java代码中更改ImageView的src? - chenzhongpu
1
这里有一个好的简单解决方案:https://dev59.com/OGct5IYBdhLWcg3wpO_H#28096369 - 全部使用Java编写,因此您可以在运行时动态地将此格式应用于图像。 - Gene Bo
你必须将ImageView放在CardView内部,因为CardView只有访问圆角属性的功能。 - Vahag Chakhoyan
31个回答

369

这是我设计的最简单的方法。请尝试。

依赖项

  • implementation 'androidx.appcompat:appcompat:1.3.0-beta01'

  • implementation 'androidx.cardview:cardview:1.0.0'

 <android.support.v7.widget.CardView
     android:layout_width="80dp"
     android:layout_height="80dp"
     android:elevation="12dp"
     android:id="@+id/view2"
    app:cardCornerRadius="40dp"
     android:layout_centerHorizontal="true"
     android:innerRadius="0dp"
     android:shape="ring"
     android:thicknessRatio="1.9">
     <ImageView
         android:layout_height="80dp"
         android:layout_width="match_parent"
         android:id="@+id/imageView1"
         android:src="@drawable/YOUR_IMAGE"
         android:layout_alignParentTop="true"
         android:layout_centerHorizontal="true">
     </ImageView>
  </android.support.v7.widget.CardView>

如果您正在使用Lollipop以上的Android版本

 <android.support.v7.widget.CardView
 android:layout_width="80dp"
 android:layout_height="80dp"
 android:elevation="12dp"
 android:id="@+id/view2"
 app:cardCornerRadius="40dp"
 android:layout_centerHorizontal="true">
 <ImageView
     android:layout_height="80dp"
     android:layout_width="match_parent"
     android:id="@+id/imageView1"
     android:src="@drawable/YOUR_IMAGE"
     android:scaleType="centerCrop"/>
   </android.support.v7.widget.CardView>

向圆形ImageView添加边框 - 最新版本

将其包装在比内部CardView略大的另一个CardView中,并将其背景颜色设置为添加圆形图像的边框。您可以增加外部CardView的大小以增加边框的厚度。

<androidx.cardview.widget.CardView
  android:layout_width="155dp"
  android:layout_height="155dp"
  app:cardCornerRadius="250dp"
  app:cardBackgroundColor="@color/white">

    <androidx.cardview.widget.CardView
      android:layout_width="150dp"
      android:layout_height="150dp"
      app:cardCornerRadius="250dp"
      android:layout_gravity="center">

        <ImageView
          android:layout_width="150dp"
          android:layout_height="150dp"
          android:src="@drawable/default_user"
          android:scaleType="centerCrop"/>

   </androidx.cardview.widget.CardView>

 </androidx.cardview.widget.CardView>

11
尝试使用此方法,似乎在 Android 5.0 以下版本无法正常工作。即使图像视图是圆形的,但图片以正方形形状显示,显得很糟糕。你有什么建议吗?在5.0及以上版本可以正常工作。 - Kaps
6
使用这种方法,我的图片不适合CardView。 - Hendra Anggrian
27
这会使卡片视图带有圆角,但图像仍然是方形的。 - kabuto178
3
我认为设置图像视图的比例类型是有意义的:android:scaleType="centerCrop" - Palm
7
谢谢。关键在于卡片的半径必须是宽度和高度的一半,才能制作出正确的圆形。 - B.shruti
显示剩余18条评论

252

您可以使用形状功能创建一个简单的白色边框和透明内容的圆形。

// res/drawable/circle.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:innerRadius="0dp"
    android:shape="ring"
    android:thicknessRatio="1.9"
    android:useLevel="false" >
    <solid android:color="@android:color/transparent" />

    <stroke
        android:width="10dp"
        android:color="@android:color/white" />
</shape>

然后创建一个layerlist drawable,并将其设置为您的ImageView的背景。

// res/drawable/img.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:drawable="@drawable/circle"/>    
    <item android:drawable="@drawable/ic_launcher"/>

</layer-list>
将其作为背景放置在您的ImageView中。
   <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/img"/>
你会得到类似这样的东西。

输入图像描述


17
然后我将那个形状设置为我的ImageView的背景?我尝试过了,但没有成功。我的图片仍然是矩形的 :( - user3050910
3
是的,使用XML,因为在移动设备上使用Java代码非常昂贵。使用这段代码后,只会在我的图像后面出现一个圆圈,而不是图像本身被切成圆形。我猜想这是边框的原因,我希望图像能够在这个圆圈内呈圆形。 - user3050910
6
仍然有些问题。除了图像前面有圆形边框外,圆形边框外部并不透明。我的意思是,圆形是存在的,然而图像的角落可见,并且超出了其后面的圆形区域。 - user3050910
91
如果我采用这种方式,如何在Java代码中更改ImageView的src? - chenzhongpu
2
不幸的是,它无法处理从URL捕获的Picasso图像。 - JorgeAmVF
显示剩余10条评论

200

使用Material Components Library,只需使用ShapeableImageView即可。
类似这样:

<com.google.android.material.imageview.ShapeableImageView
    app:shapeAppearanceOverlay="@style/roundedImageViewRounded"
    app:strokeColor="@color/....."
    app:strokeWidth="1dp"
    ...
    />

随着:

  <style name="roundedImageViewRounded">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">50%</item>
  </style>

enter image description here

注意: 至少需要版本1.2.0


使用 Jetpack Compose,您可以使用 CircleShape 应用 clip 修饰符:

Image(
    painter = painterResource(R.drawable.xxxx),
    contentDescription = "xxxx",
    contentScale = ContentScale.Crop,
    modifier = Modifier
        .size(100.dp)
        .clip(CircleShape)
        .border(2.dp, Color.Blue, CircleShape)
)

输入图像描述


27
这应该是被接受的答案。终于有像Google Material这样的人提出了一个圆角图片视图解决方案,可以消除人们仍在使用的所有糟糕的第三方库。此外,我不建议在Glide上使用变换,因为如果你使用占位符,Glide不允许你将变换添加到占位符中,可悲的是。因此,这个答案解决了所有问题,并且最容易使用。 - M'aiq the Coder
3
功能正常,应该被接受为答案。唯一注意到的是图像必须是一个完美的正方形(这并不适用于我的情况,因为我有一个带有与约束匹配的可绘制项的约束布局)。像往常一样,Gabriele 的工作很好! - m.i.n.a.r.
1
非常需要的库。运行良好。 - Waheed Akhtar
4
android:scaleType="centerCrop"应用于不完美正方形的图片几乎可以解决问题。 - Abu Saeed
1
边框不是完美的圆形,两侧变平了。有什么解决办法吗? - John T
显示剩余3条评论

180
希望这能对你有所帮助。
1)ShapeableImageView

enter image description here

<com.google.android.material.imageview.ShapeableImageView
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:padding="5dp"
        app:strokeWidth="10dp"
        app:strokeColor="@android:color/darker_gray"
        app:shapeAppearanceOverlay="@style/circleImageView"
        android:src="@drawable/profile"
        android:layout_margin="10dp"/>


 Style add here: res/values/style.xml or res/values/themes.xml
<style name="circleImageView" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">50%</item>
  </style>

不要忘记实施:Gradle脚本 > build.gradle(模块:app)> 依赖项
     implementation 'com.google.android.material:material:1.10.0'  

完整的描述请查看这里:这里的来源。

2) CircleImageView

enter image description here

 <de.hdodenhof.circleimageview.CircleImageView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/profile_image"
    android:layout_width="96dp"
    android:layout_height="96dp"
    android:src="@drawable/profile"
    app:civ_border_width="2dp"
    app:civ_border_color="#FF000000"/>

不要忘记实施:Gradle脚本 > build.gradle(模块:app)> 依赖项
     implementation 'de.hdodenhof:circleimageview:3.1.0'   
        

完整描述请查看这里:这里的来源。

3) CircularImageView

enter image description here

<com.mikhaellopez.circularimageview.CircularImageView
    android:layout_width="250dp"
    android:layout_height="250dp"
    android:src="@drawable/image"
    app:civ_border_color="#3f51b5"
    app:civ_border_width="4dp"
    app:civ_shadow="true"
    app:civ_shadow_radius="10"
    app:civ_shadow_color="#3f51b5"/>

不要忘记实施:Gradle脚本 > build.gradle(模块:app)> 依赖项
     implementation 'com.mikhaellopez:circularimageview:4.3.1'   
        

请点击此处查看完整描述:源链接。

1
如何将灰色部分改为白色? - John Joe
2
自发布此内容以来已经有更新。border_colour和border_width已更名。请查看Github页面以获取更多信息:https://github.com/hdodenhof/CircleImageView - rharvey
不支持比例类型。:( - User
我在某些设备上收到了错误报告。 - M at
1
实际上,第三方库是最好的解决方案,并且它与使用Picasso从URL捕获的图像非常兼容。 - JorgeAmVF
显示剩余4条评论

74

借助 glide 库和 RoundedBitmapDrawableFactory 类的帮助,实现这一目标变得十分容易。您可能需要创建一个圆形占位图像。

Glide V4:

Glide.with(context).load(url).apply(RequestOptions.circleCropTransform()).into(imageView);

Glide V3:

    Glide.with(context)
        .load(imgUrl)
        .asBitmap()
        .placeholder(R.drawable.placeholder)
        .error(R.drawable.placeholder)
        .into(new BitmapImageViewTarget(imgProfilePicture) {
            @Override
            protected void setResource(Bitmap resource) {
                RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(context.getResources(),
                        Bitmap.createScaledBitmap(resource, 50, 50, false));
                drawable.setCircular(true);
                imgProfilePicture.setImageDrawable(drawable);
            }
        });

对于PicassoRoundedTransformation,这是一个非常好的解决方案,可以在图像的顶部或底部边缘提供圆角选项。


3
不确定您在此示例中使用的 Glide 版本,但是在 v4.0.0 中,您可以直接使用 RequestOptions 而不是 RoundedBitmapDrawable:Glide.with(context).load(imgUrl).apply(new RequestOptions().centerCrop()) .into(imageView) - Eugene Brusov
3
你的意思是:Glide.with(context).load(imgUrl).apply(new RequestOptions().circleCrop()) .into(imageView)? - Androidz
3
在版本4.6.1中,请使用.apply(RequestOptions.circleCropTransform()) - Pavel
2
在 Glide v.4 中,如果 GlideApp 在应用程序中进行了配置:GlideApp.with(this).load(url).circleCrop().into(imageView); - CoolMind
1
我简直不敢相信它如此轻松地运行,没有任何麻烦。 - Ajeeli
1
V4运行得非常好 - Khalid Lakhani

34

如果使用src属性,上述方法似乎不起作用。我所做的是将两个图像视图放在一个帧布局中,一个在另一个上方,如下所示:

<FrameLayout android:id="@+id/frame"
             android:layout_width="40dp"
             android:layout_height="40dp">

    <ImageView android:id="@+id/pic"
               android:layout_width="40dp"
               android:layout_height="40dp"
               android:src="@drawable/my_picture" />

    <ImageView android:id="@+id/circle_crop"
               android:layout_width="40dp"
               android:layout_height="40dp"
               android:src="@drawable/circle_crop" />

</FrameLayout>

将一个圆形裁剪的.png文件放在drawable文件夹中,该文件应与图像尺寸相同(在我这里是正方形),具有白色背景和中心的透明圆形。如果您想要一个正方形的imageview,可以使用此图片。

圆形图片

只需下载上面的图片即可。


2
最佳解决方案!最佳性能。更改位图是内存问题。 - itzhar
这个示例图片是白色的,所以你可以在任何颜色下创建自己的图片或下载这张图片并改变它的颜色。 - Jyotman Singh
请问如何将图像颜色更改为黑色?这可以在Android Studio内完成还是需要外部工具(显然我不熟悉图像处理)? - Zvi
不是在Android Studio内部。你需要像Photoshop这样的工具。这张照片本身也是用Photoshop创建的。 - Jyotman Singh
2
你可以给圆形可绘制对象添加一个颜色过滤器:circleCrop.setColorFilter(getResources().getColor(R.color.white))。这样,你就可以拥有任何颜色的单个圆形可绘制对象,并在应用程序中的任何背景上重复使用它。只需每次设置适当的颜色资源的颜色过滤器即可。 - mjp66

20
以下是其中最简单的方法之一,使用以下代码: 依赖项
dependencies {
    ...
    compile 'de.hdodenhof:circleimageview:2.1.0'      // use this or use the latest compile version. In case u get bug.
}

XML 代码

<de.hdodenhof.circleimageview.CircleImageView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/profile_image"
    android:layout_width="96dp"             //  here u can adjust the width 
    android:layout_height="96dp"            //  here u can adjust the height 
    android:src="@drawable/profile"         //  here u can change the image 
    app:civ_border_width="2dp"              //  here u can adjust the border of the circle.  
    app:civ_border_color="#FF000000"/>      //  here u can adjust the border color

截图:

屏幕截图

来源:CircleImageView GitHub 代码库

输入图片说明


6
不支持比例类型。:( - User

14

你不需要任何第三方库。

你可以使用材料中的ShapeableImageView

implementation 'com.google.android.material:material:1.2.0'

style.xml

<style name="ShapeAppearanceOverlay.App.CornerSize">
     <item name="cornerSize">50%</item>
</style>

布局中

<com.google.android.material.imageview.ShapeableImageView
     android:layout_width="100dp"
     android:layout_height="100dp"
     app:srcCompat="@drawable/ic_profile"
     app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.CornerSize"
/>

您可以查看这个:

https://developer.android.com/reference/com/google/android/material/imageview/ShapeableImageView

或者这个:

https://medium.com/android-beginners/shapeableimageview-material-components-for-android-cac6edac2c0d


如果这个解决方案不起作用,请参考这个答案 - lasec0203
1
朋友,你忘记在styles.xml文件中加入一个非常重要的属性了。正如你分享的第二个链接所述,如果没有parent = "",它将无法工作:<style name="ShapeAppearanceOverlay.App.CornerSize50Percent" parent=""> <item name="cornerSize">50%</item> </style> - Ramiro G.M.

12

您可以简单地使用AndroidX ImageFilterView

 <androidx.constraintlayout.utils.widget.ImageFilterView
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_marginStart="@dimen/margin_medium"
        android:layout_marginBottom="@dimen/margin_medium"
        android:background="@color/white"
        android:padding="@dimen/margin_small"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:roundPercent="1"
        app:srcCompat="@drawable/ic_gallery" />

ImageFilterView示例图片


我发现这是解决这个问题最有效的方法。 - undefined

9

您可以直接使用CardView,无需任何外部库

  <androidx.cardview.widget.CardView
                    android:id="@+id/roundCardView"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:layout_centerHorizontal="true"
                    android:elevation="0dp"
                    app:cardCornerRadius="20dp">

                    <ImageView
                        android:layout_width="40dp"
                        android:layout_height="40dp"
                        android:src="@drawable/profile" />
</androidx.cardview.widget.CardView>

最简单的方法是…… - Prajwal Waingankar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接