【问题标题】:ImageView in circular through XML通过 XML 循环的 ImageView
【发布时间】:2014-04-02 01:57:40
【问题描述】:

我想将我的ImageView 中的任何图像制作成带边框的圆形。

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

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

【问题讨论】:

  • java代码中如何更改ImageView的src?
  • 这里有很好的简单解决方案stackoverflow.com/a/28096369/2162226 - 全部使用 Java,因此您可以在运行时动态将此格式应用于图像
  • 你必须把你的 ImageView 放在 CardView 里面,因为 CardView 只有访问圆角半径属性的功能。

标签: android xml imageview


【解决方案1】:

这是我设计的最简单的方式。试试这个。

依赖

  • 实现'androidx.appcompat:appcompat:1.3.0-beta01'

  • 实现'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>
    

    如果您正在使用棒棒糖以上的 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 的大小来增加边框的粗细。

<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>

【讨论】:

  • 谢谢。简单,易于内存使用。到目前为止,我尝试过的库在 RecyclerView 项目中使用自定义视图时都会给出 OOMExceptions。
  • 用这个试过了,好像在5.0以下的安卓上不行。尽管图像视图是圆形的,但图像较小且呈方形,看起来很糟糕。有什么建议吗? 5.0 及以上版本运行良好。
  • 我的图片不适合 CardView 这个方法
  • 这会使卡片视图变圆,但图像下方仍然是正方形
  • 谢谢,这里的关键是卡片半径必须是宽度和高度的一半才能形成一个正确的圆。
【解决方案2】:

您可以制作一个带有白色边框和透明内容的简单圆形。

// 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>

然后制作一个可绘制的图层列表并将其作为图像视图的背景。

// 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
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/img"/>

你会有类似的东西。

【讨论】:

  • 然后我将该形状设置为我的图像视图的背景?我已经尝试过了,但没有奏效。我的图像仍然是矩形 :(
  • 是的,使用 XML,因为使用 java 代码对移动设备来说非常昂贵。使用此代码,它只会在我的图像后面出现一个圆圈,而不是图像本身是一个圆圈。我想是为了边界,我希望我的图像在这个范围内被围成一个圆圈
  • 但还是有问题。除了图像前面有圆形边框外,它在圆形之外是不透明的。我的意思是,圆圈在那里,但是,图像的角是可见的,并且超出了它后面的圆圈区域
  • 如果我采用这种方式,如何更改java代码中ImageView的src?
  • 很遗憾,它不适用于从 URL 捕获的毕加索图像。
【解决方案3】:

希望对你有帮助。

1) CircleImageView

 <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 Scripts > build.gradle (Module: app) > dependencies

     implementation 'de.hdodenhof:circleimageview:3.1.0'   
        

完整的描述请看这里:The Source here.

2) CircularImageView

<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 Scripts > build.gradle (Module: app) > dependencies

     implementation 'com.mikhaellopez:circularimageview:4.3.0'   
        

完整的描述请看这里:The Source here.

【讨论】:

  • 如何将灰色部分变为白色?
  • 自发布以来已有更新。已重命名border_colour 和border_width。查看 github 页面了解更多信息:github.com/hdodenhof/CircleImageView
  • 不支持刻度类型。 :(
  • 嗨,使用 src 设置时它工作正常,但尝试使用 java 代码设置时它的行为不同
  • @Erum 您只需将 compile 'de.hdodenhof:circleimageview:1.3.0' 放在 gradle 文件中,不需要 java 代码。
【解决方案4】:

使用 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>

注意:至少需要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)
)

【讨论】:

  • 这应该是公认的答案。最后,像 Google Material 这样的人想出了一个圆角 imageVview 解决方案,它杀死了人们仍在使用的所有写得不好的第三方库。另外,我不建议在 Glide 上使用转换,因为如果您使用占位符,Glide 也不允许您将转换添加到占位符,遗憾的是。所以这个答案解决了所有问题并且最容易使用。
  • 按应有的方式工作,并且应该是公认的答案。我唯一注意到的是图像必须是一个完美的正方形(这不是我的情况,因为我有一个约束布局和一个与约束匹配的可绘制对象)。 Gabriele 一如既往的出色!
  • 非常需要的库。效果很好。
  • 由于某种原因,50% 的角尺寸使图像对我来说是不可见的。将其更改为 49% 即可修复。
  • 以编程方式截取屏幕截图时,图像变为带黑角的正方形
【解决方案5】:

glide 库和RoundedBitmapDrawableFactory 类的帮助下,很容易实现。您可能需要创建圆形占位符图像。

滑翔 V4:

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

滑翔 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);
            }
        });

对于 Picasso RoundedTransformation,这是一个非常棒的解决方案,它提供了在顶部或底部边缘舍入图像的额外选项。

【讨论】:

  • 不确定你在这个例子中使用的是什么版本的 glide,但是在 v4.0.0 中你可以简单地使用他们的 RequestOptions 而不是 RoundedBitmapDrawable:Glide.with(context).load(imgUrl).apply(new RequestOptions().centerCrop()) .into(imageView)
  • 你不是说; Glide.with(context).load(imgUrl).apply(new RequestOptions().circleCrop()) .into(imageView) ?
  • 在 4.6.1 版本中使用 .apply(RequestOptions.circleCropTransform())
  • 如果在应用程序中配置了GlideApp,则在 Glide v.4 中:GlideApp.with(this).load(url).circleCrop().into(imageView);
  • 如果没有头痛,我简直不敢相信它这么容易工作
【解决方案6】:

如果您使用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>

只需在您的可绘制文件夹中放置一个 circle_crop.png,该文件夹的形状与您的图像尺寸(在我的情况下为正方形)相同,具有白色背景和中心透明圆圈。如果你想要一个方形的图像视图,你可以使用这个图像。

只需下载上面的图片。

【讨论】:

  • 最佳解决方案!最棒的表演。更改位图是内存问题
  • 这个示例图片是白色的,所以是的。但是您可以创建自己的任何颜色的图像或下载此图像并更改其颜色。
  • 您能解释一下如何将图像的颜色更改为黑色吗?可以从 Android Studio 内部完成还是我需要一个外部工具(可以看到我不熟悉图像创建)
  • 不是来自 Android Studio 内部。你需要像Photoshop这样的东西。这张照片本身也是用 Photoshop 制作的
  • 你可以给圆形drawable一个颜色过滤器:circleCrop.setColorFilter(getResources().getColor(R.color.white))。通过这种方式,您可以绘制一个任意颜色的圆形,并在您的应用程序的任何背景中的任何位置重复使用它。每次只需使用适当的颜色资源设置一个颜色过滤器。
【解决方案7】:

以下是最简单的方法之一,使用以下代码:

依赖关系

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

截图:

来源:Circular ImageView GitHub Repository

【讨论】:

  • 不支持刻度类型。 :(
【解决方案8】:

您不需要任何第三方库。

您可以在材料中使用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

【讨论】:

  • 如果此解决方案不起作用,请参阅此answer
  • 朋友,你忘了在styles.xml 文件中添加一个非常重要的属性。如您共享的第二个链接中所述,如果没有 parent="",它将无法工作:
【解决方案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>

【讨论】:

    【解决方案10】:

    这样就可以了:

    矩形.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <solid android:color="@android:color/transparent" />
        <padding android:bottom="-14dp" android:left="-14dp" android:right="-14dp" android:top="-14dp" />
    
    </shape>
    

    circle.xml

    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:innerRadius="0dp"
        android:shape="oval"
    
        android:useLevel="false" >
        <solid android:color="@android:color/transparent" />
    
        <stroke
            android:width="15dp"
            android:color="@color/verification_contact_background" />
    
    </shape>
    

    profile_image.xml(图层列表)

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

    你的布局

     <ImageView
            android:id="@+id/profile_image"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/default_org"
            android:src="@drawable/profile_image"/>
    

    【讨论】:

    • 什么是 default_org ?
    • 这可以是任何占位符图片
    • 在这种情况下,矩形尺寸图像的边缘将穿过圆的边界。如何在圆内准确定位每个维度和形式的每个图像?
    【解决方案11】:

    最佳解决方案礼貌https://www.youtube.com/watch?v=0MHoNU7ytaw 卡片视图的宽度和高度决定了它所包含的图片大小设置如下:

    1. 为 Gradle(模块)添加依赖项
    2. 将xml代码添加到activity.xml或fragment.xml文件中
        implementation 'androidx.cardview:cardview:1.0.0'
    
       <androidx.cardview.widget.CardView
          android:layout_width="300dp"
          android:layout_height="270dp"
          android:layout_gravity="center"
          app:cardCornerRadius="150dp"
          app:cardBackgroundColor="@color/trans"
          >
        <ImageView
            android:id="@+id/resultImage"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/congrats"
            android:layout_gravity="center">
    
        </ImageView>
    
    
      </androidx.cardview.widget.CardView>```
    
    

    【讨论】:

      【解决方案12】:

      我使用 shape = "oval" 而不是下面的 "ring"。它对我有用。为了使图像保持在界限内,我使用&lt;padding&gt; 并在&lt;ImageView&gt; 中将&lt;adjustViewBounds&gt; 设置为true。我尝试过使用尺寸在 50 x 50 px 到 200x200 px 之间的图像。

      【讨论】:

      • 您也可以添加以下内容android:scaleType="fitCenter"
      【解决方案13】:

      2021 年更新:使用 Glide v4 CircleCrop 参见 https://bumptech.github.io/glide/doc/generatedapi.html

          implementation 'com.github.bumptech.glide:glide:4.11.0'
          annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
      

      XML

      <ImageView
          android:id="@+id/vinyl"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          tools:ignore="ContentDescription" />
      

      在代码中

          Glide.with(this)
                  .load("https://images.pexels.com/photos/3828241/pexels-photo-3828241.jpeg")
                  .transform(CircleCrop())
                  .into(rootView.findViewById<ImageView>(R.id.vinyl))
      

      【讨论】:

      • 谢谢,我会投赞成票,但不能鼓励下流。
      【解决方案14】:

      @Jyotman Singh,答案非常好(对于纯色背景),所以我想通过分享可以根据您的需要重新着色的矢量可绘制来增强它,也很方便,因为矢量单件形状很好可扩展。

      这是矩形圆形(@drawable/shape_round_profile_pic):

      <?xml version="1.0" encoding="utf-8"?>
      <vector xmlns:android="http://schemas.android.com/apk/res/android"
          android:viewportWidth="284"
          android:viewportHeight="284"
          android:width="284dp"
          android:height="284dp">
          <path
              android:pathData="M0 142L0 0l142 0 142 0 0 142 0 142 -142 0 -142 0zm165 137.34231c26.06742 -4.1212 52.67405 -17.543 72.66855 -36.65787 11.82805 -11.30768 20.55487 -22.85153 27.7633 -36.72531C290.23789 158.21592 285.62874 101.14121 253.48951 58.078079 217.58149 9.9651706 154.68849 -10.125717 98.348685 8.5190299 48.695824 24.95084 12.527764 67.047123 3.437787 118.98655 1.4806194 130.16966 1.511302 152.96723 3.4990422 164.5 12.168375 214.79902 47.646316 256.70775 96 273.76783c21.72002 7.66322 44.26673 9.48476 69 5.57448z"
              android:fillColor="#ffffff" /> // you can change frame color
      </vector>
      

      用法同理:

      <FrameLayout
              android:layout_width="70dp"
              android:layout_height="70dp">
      
              <ImageView
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:background="@drawable/YOUR_PICTURE" />
      
              <ImageView
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:background="@drawable/shape_round_profile_pic"/>
      
          </FrameLayout>
      

      【讨论】:

      • 这应该如何工作?您只需在图像上方显示一个圆圈,而实际询问的是如何裁剪图像,使其看起来像一个圆圈。
      • 请参阅上面@Jyotman Singh 的回答。这对我很有帮助,所以我对其进行了一些改进。要裁剪图像,您可以使用:GlideApp.with(getApplicationContext()).asBitmap().load(profilePhotoUrl) .circleCrop()
      • 感谢您提供的圆形矩形!正是我需要的!
      【解决方案15】:

      您可以简单地使用 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" />
      

      【讨论】:

        【解决方案16】:

        只需使用这几行代码即可完成:

        <de.hdodenhof.circleimageview.CircleImageView
                    xmlns:app="http://schemas.android.com/apk/res-auto"
                    android:clickable="true"
                    app:civ_border_width="3dp"
                    app:civ_border_color="#FFFFFFFF"
                    android:id="@+id/profile"
                    android:layout_width="200dp"
                    android:layout_height="200dp"
                    android:layout_below="@+id/header_cover_image"
                    android:layout_centerHorizontal="true"
                    android:layout_marginTop="-130dp"
                    android:elevation="5dp"
                    android:padding="20dp"
                    android:scaleType="centerCrop"
                    android:src="@drawable/profilemain" />
        

        别忘了导入:

        import de.hdodenhof.circleimageview.CircleImageView;
        

        在 build.gradle 中添加这个库:

        compile 'de.hdodenhof:circleimageview:2.1.0'
        

        【讨论】:

        • 你一定在java类中遗漏了一些东西
        【解决方案17】:

        发布此答案以供将来参考。您可以使用com.google.android.material:material 中的ShapeableImageView

        <com.google.android.material.imageview.ShapeableImageView
            android:id="@+id/img_launcher_icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_margin="5dp"
            android:adjustViewBounds="true"
            android:background="@android:color/transparent"
            android:elevation="5dp"
            android:maxWidth="50dp"
            android:maxHeight="50dp"
            android:scaleType="fitXY"
            android:src="@mipmap/ic_launcher"
            app:shapeAppearance="?attr/actionButtonStyle"
            app:shapeAppearanceOverlay="@style/imageViewRounded"
            app:strokeColor="@android:color/white" />
        

        在您的styles.xml 中添加imageViewRounded 样式

        <style name="imageViewRounded">
            <item name="cornerFamily">rounded</item>
            <item name="cornerSize">51%</item>
        </style>
        

        如果没有添加,你可以添加材料设计依赖。

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

        设计看起来像

        【讨论】:

          【解决方案18】:

          如果您在应用中使用 Material Design,请使用它

          <com.google.android.material.card.MaterialCardView
                      android:layout_width="75dp"
                      android:layout_height="75dp"
                      app:cardCornerRadius="50dp"
                      app:strokeWidth="1dp"
                      app:strokeColor="@color/black">
                      <ImageView
                          android:layout_width="fill_parent"
                          android:layout_height="fill_parent"
                          android:id="@+id/circular_image"
                          android:scaleType="fitCenter"
                          android:src="@drawable/your_img" />
                  </com.google.android.material.card.MaterialCardView>
          

          【讨论】:

            【解决方案19】:

            我就是这样做的,我在矢量图像中使用了我的背景颜色

            ic_bg_picture.xml

             <vector xmlns:android="http://schemas.android.com/apk/res/android"
                android:width="100dp"
                android:height="100dp"
                android:viewportWidth="100"
                android:viewportHeight="100">
              <path
                  android:pathData="M100.6,95.5c0,-0.4 -0.1,-0.7 0,-1.1c-0.2,-0.7 -0.2,-1.4 -0.1,-2.1c0,-0.1 0,-0.2 0,-0.3c-0.1,-0.6 -0.1,-1.2 0,-1.8c-1,-1.3 -0.3,-2.9 -0.3,-4.3c-0.1,-28.7 -0.1,-57.3 -0.1,-86C68,-0.1 35.9,-0.1 3.8,-0.2C0.7,-0.2 0,0.5 0,3.6c0.1,32.1 0.1,64.2 0.1,96.2c31,0 62,-0.1 92.9,0.1c3.6,0 6.3,-0.2 7.5,-3.2C100.5,96.4 100.5,95.9 100.6,95.5zM46.3,95.2C26.4,94 2,74.4 3.8,46.8C5.1,27.2 24.4,2.7 52.6,4.6c20.2,1.4 43,21.3 41.5,45.1C96.1,72.4 73,96.8 46.3,95.2z"
                  android:fillColor="#6200EE"/>
            </vector>
            

            在我的例子中,我创建了一个向量并更改了 android:fillColor="#6200EE"

            根据我的背景颜色

              <ImageView
                android:id="@+id/iv_profile_image"
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:contentDescription="@string/app_name"
                app:srcCompat="@color/colorPrimaryDark" />
            
            <ImageView
                android:id="@+id/container_profile_image"
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:contentDescription="@string/app_name"
                app:srcCompat="@drawable/ic_bg_picture"/>
            

            【讨论】:

              【解决方案20】:

              试试这个。

              public class RoundedImageView extends android.support.v7.widget.AppCompatImageView {
              
                  private int borderWidth = 4;
                  private int viewWidth;
                  private int viewHeight;
                  private Bitmap image;
                  private Paint paint;
                  private Paint paintBorder;
                  private BitmapShader shader;
              
                  public RoundedImageView(Context context)
                  {
                      super(context);
                      setup();
                  }
              
                  public RoundedImageView(Context context, AttributeSet attrs)
                  {
                      super(context, attrs);
                      setup();
                  }
              
                  public RoundedImageView(Context context, AttributeSet attrs, int defStyle)
                  {
                      super(context, attrs, defStyle);
                      setup();
                  }
              
                  private void setup()
                  {
                      paint = new Paint();
                      paint.setAntiAlias(true);
              
                      paintBorder = new Paint();
                      setBorderColor(Color.WHITE);
                      paintBorder.setAntiAlias(true);
                      this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
              
                      paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.WHITE);
                  }
              
                  public void setBorderWidth(int borderWidth)
                  {
                      this.borderWidth = borderWidth;
                      this.invalidate();
                  }
              
                  public void setBorderColor(int borderColor)
                  {
                      if (paintBorder != null)
                          paintBorder.setColor(borderColor);
              
                      this.invalidate();
                  }
              
                  private void loadBitmap()
                  {
                      BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();
              
                      if (bitmapDrawable != null)
                          image = bitmapDrawable.getBitmap();
                  }
              
                  @SuppressLint("DrawAllocation")
                  @Override
                  public void onDraw(Canvas canvas)
                  {
                      loadBitmap();
              
                      if (image != null)
                      {
                          shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
                          paint.setShader(shader);
                          int circleCenter = viewWidth / 2;
                          canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter + borderWidth - 4.0f, paintBorder);
                          canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter - 4.0f, paint);
                      }
                  }
              
                  @Override
                  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
                  {
                      int width = measureWidth(widthMeasureSpec);
                      int height = measureHeight(heightMeasureSpec, widthMeasureSpec);
              
                      viewWidth = width - (borderWidth * 2);
                      viewHeight = height - (borderWidth * 2);
              
                      setMeasuredDimension(width, height);
                  }
              
                  private int measureWidth(int measureSpec)
                  {
                      int result = 0;
                      int specMode = MeasureSpec.getMode(measureSpec);
                      int specSize = MeasureSpec.getSize(measureSpec);
              
                      if (specMode == MeasureSpec.EXACTLY)
                      {
                          result = specSize;
                      }
                      else
                      {
                          // Measure the text
                          result = viewWidth;
                      }
              
                      return result;
                  }
              
                  private int measureHeight(int measureSpecHeight, int measureSpecWidth)
                  {
                      int result = 0;
                      int specMode = MeasureSpec.getMode(measureSpecHeight);
                      int specSize = MeasureSpec.getSize(measureSpecHeight);
              
                      if (specMode == MeasureSpec.EXACTLY)
                      {
                          result = specSize;
                      }
                      else
                      {
                          result = viewHeight;
                      }
              
                      return (result + 2);
                   }
               }
              

              并在布局中使用此 ImageView,例如:

              <com.app.Demo.RoundedImageView
                   android:id="@+id/iv_profileImage"
                   android:layout_width="70dp"
                   android:layout_height="70dp"
                   android:layout_centerHorizontal="true"
                  />
              

              【讨论】:

                【解决方案21】:

                这个类是带有阴影、描边、饱和度的自定义圆形图像视图,使用这个自定义圆形图像视图,您可以使您的图像具有半径的圆形形状。圆形阴影ImageView的家伙不需要Github这个类就足够了。

                将 CircularImageView 添加到您的布局中

                CircularImageView c=new CircularImageView(this,screen width,screen height,Bitmap myimage);
                yourLayout.addView(c);**
                
                
                public class CircularImageView extends android.support.v7.widget.AppCompatImageView  
                {
                    private final Context context;
                    private final int width, height;
                    private final Paint paint;
                    private final Paint paintBorder,imagePaint;
                    private final Bitmap bitmap2;
                    private final Paint paint3;
                    private Bitmap bitmap;
                    private BitmapShader shader;
                    private float radius = 4.0f;
                    float x = 0.0f;
                    float y = 8.0f;
                    private float stroke;
                    private float strokeWidth = 0.0f;
                    private Bitmap bitmap3;
                    private int corner_radius=50;
                
                
                    public CircularImageView(Context context, int width, int height, Bitmap bitmap)     {
                        super(context);
                        this.context = context;
                        this.width = width;
                        this.height = height;
                
                   //here "bitmap" is the square shape(width* width) scaled bitmap ..
                
                        this.bitmap = bitmap;
                
                
                        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
                        paint.setAntiAlias(true);
                        paint.setFilterBitmap(true);
                        paint.setDither(true);
                
                
                        paint3=new Paint();
                        paint3.setStyle(Paint.Style.STROKE);
                        paint3.setColor(Color.WHITE);
                        paint3.setAntiAlias(true);
                
                        paintBorder = new Paint();
                        imagePaint= new Paint();
                
                        paintBorder.setColor(Color.WHITE);
                        paintBorder.setAntiAlias(true);
                        this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
                
                
                        this.bitmap2 = Bitmap.createScaledBitmap(bitmap, (bitmap.getWidth() - 40), (bitmap.getHeight() - 40), true);
                
                
                        imagePaint.setAntiAlias(true);
                
                
                
                
                        invalidate();
                    }
                
                    @Override
                    protected void onDraw(Canvas canvas) 
                    {
                        super.onDraw(canvas);
                        Shader b;
                         if (bitmap3 != null)
                            b = new BitmapShader(bitmap3, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
                         else
                            b = new BitmapShader(bitmap2, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
                        imagePaint.setShader(b);
                        canvas.drawBitmap(maskedBitmap(), 20, 20, null);
                    }
                
                    private Bitmap maskedBitmap()
                    {
                        Bitmap l1 = Bitmap.createBitmap(width,width, Bitmap.Config.ARGB_8888);
                        Canvas canvas = new Canvas(l1);
                        paintBorder.setShadowLayer(radius, x, y, Color.parseColor("#454645"));
                        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
                        final RectF rect = new RectF();
                        rect.set(20, 20, bitmap2.getWidth(), bitmap2.getHeight());
                
                        canvas.drawRoundRect(rect, corner_radius, corner_radius, paintBorder);
                
                        canvas.drawRoundRect(rect, corner_radius, corner_radius, imagePaint);
                
                        if (strokeWidth!=0.0f)
                        {
                            paint3.setStrokeWidth(strokeWidth);
                            canvas.drawRoundRect(rect, corner_radius, corner_radius, paint3);
                        }
                
                         paint.setXfermode(null);
                        return l1;
                    }
                
                
                
                
                     // use seekbar here, here you have to pass  "0 -- 250"  here corner radius will change 
                
                    public void setCornerRadius(int corner_radius)
                    {
                        this.corner_radius = corner_radius;
                        invalidate();
                    }
                
                
                
                    -------->use seekbar here, here you have to pass  "0 -- 10.0f"  here shadow radius will change 
                
                    public void setShadow(float radius)
                    {
                        this.radius = radius;
                        invalidate();
                    }
                
                   // use seekbar here, here you have to pass  "0 -- 10.0f"  here stroke size  will change 
                
                    public void setStroke(float stroke)
                    {
                        this.strokeWidth = stroke;
                        invalidate();
                    }
                
                    private Bitmap updateSat(Bitmap src, float settingSat)
                    {
                
                        int w = src.getWidth();
                        int h = src.getHeight();
                
                        Bitmap bitmapResult =
                                Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
                        Canvas canvasResult = new Canvas(bitmapResult);
                        Paint paint = new Paint();
                        ColorMatrix colorMatrix = new ColorMatrix();
                        colorMatrix.setSaturation(settingSat);
                        ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
                        paint.setColorFilter(filter);
                        canvasResult.drawBitmap(src, 0, 0, paint);
                
                        return bitmapResult;
                    }
                
                
                
                
                  // use seekbar here, here you have to pass  "0 -- 2.0f"  here saturation  will change 
                
                    public void setSaturation(float sat)
                    {
                        System.out.println("qqqqqqqqqq            "+sat);
                        bitmap3=updateSat(bitmap2, sat);
                
                        invalidate();
                    } 
                
                
                }
                
                
                
                
                
                
                        // Seekbar to change radius
                
                                  radius_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                                        @Override
                                        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
                                        {
                                            text_radius.setText(""+progress);
                                            circularImageView.setCornerRadius(progress);
                                        }
                
                                        @Override
                                        public void onStartTrackingTouch(SeekBar seekBar) {
                
                                        }
                
                                        @Override
                                        public void onStopTrackingTouch(SeekBar seekBar) {
                
                                        }
                                    });
                
                
                     // Seekbar to change shadow
                
                                    shadow_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                                        @Override
                                        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
                                        {
                                            float f= 4+progress/10.0f;
                                            text_shadow.setText(""+progress);
                                            circularImageView.setShadow(f);
                                        }
                
                                        @Override
                                        public void onStartTrackingTouch(SeekBar seekBar) {
                
                                        }
                
                                        @Override
                                        public void onStopTrackingTouch(SeekBar seekBar) {
                
                                        }
                                    });
                
                
                           // Seekbar to change saturation
                
                                    saturation_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                                        @Override
                                        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
                                        {
                                            int progressSat = saturation_seekbar.getProgress();
                                            float sat = (float) ((progressSat*4 / 100.0f)-1.0f);
                                            circularImageView.setSaturation(sat);
                
                                            text_saturation.setText(""+progressSat);
                                        }
                
                                        @Override
                                        public void onStartTrackingTouch(SeekBar seekBar) {
                
                                        }
                
                                        @Override
                                        public void onStopTrackingTouch(SeekBar seekBar) {
                
                                        }
                                    });
                
                
                    // Seekbar to change stroke
                
                                    stroke_seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                                        @Override
                                        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
                                        {
                                            if (progress==0)
                                            {
                                                float f=(progress*10.0f/100.0f);
                                                circularImageView.setStroke(f);
                                            }
                                            else
                                            {
                                                float f=(progress*10.0f/100.0f);
                                                circularImageView.setStroke(f);
                                            }
                
                                            text_stroke.setText(""+progress);
                                        }
                
                                        @Override
                                        public void onStartTrackingTouch(SeekBar seekBar) {
                
                                        }
                
                                        @Override
                                        public void onStopTrackingTouch(SeekBar seekBar) {
                
                                        }
                                    });
                
                
                
                
                             //radius seekbar in xml file
                
                             <SeekBar
                                android:layout_width="match_parent"
                                android:layout_gravity="center" 
                                android:progress="50"
                                android:max="250"
                                android:id="@+id/radius_seekbar"
                                android:layout_height="wrap_content" />
                
                
                
                
                
                          //saturation seekbar in xml file
                
                             <SeekBar
                                android:layout_width="match_parent"
                                android:layout_gravity="center" 
                                android:progress="50"
                                android:max="100"
                                android:id="@+id/saturation_seekbar"
                                android:layout_height="wrap_content" />
                
                
                
                
                
                    //shadow seekbar in xml file
                
                             <SeekBar
                                android:layout_width="match_parent"
                                android:layout_gravity="center" 
                                android:progress="0"
                                android:max="100"
                                android:id="@+id/shadow_seekbar"
                                android:layout_height="wrap_content" />
                
                
                
                
                         //stroke seekbar in xml file
                
                             <SeekBar
                                android:layout_width="match_parent"
                                android:layout_gravity="center" 
                                android:progress="0"
                                android:max="100"
                                android:id="@+id/stroke _seekbar"
                                android:layout_height="wrap_content" />
                

                【讨论】:

                  【解决方案22】:

                  实际上,您可以使用 Google 通过支持库 RoundedBitmapDrawableFactory 类(herehere)提供的东西,而不是使用第三方库:

                  分级:

                  implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
                  

                  MainActivity.kt

                  class MainActivity : AppCompatActivity() {
                  
                      override fun onCreate(savedInstanceState: Bundle?) {
                          super.onCreate(savedInstanceState)
                          setContentView(R.layout.activity_main)
                          val originalDrawable = ContextCompat.getDrawable(this, R.drawable.avatar_1)!!
                          val bitmap = convertDrawableToBitmap(originalDrawable)
                          val drawable = RoundedBitmapDrawableFactory.create(resources, bitmap)
                          drawable.setAntiAlias(true)
                          drawable.cornerRadius = Math.max(bitmap.width, bitmap.height) / 2.0f
                          avatarImageView.setImageDrawable(drawable)
                      }
                  
                      companion object {
                          @JvmStatic
                          fun convertDrawableToBitmap(drawable: Drawable): Bitmap {
                              if (drawable is BitmapDrawable)
                                  return drawable.bitmap
                              // We ask for the bounds if they have been set as they would be most
                              // correct, then we check we are  > 0
                              val bounds = drawable.bounds
                              val width = if (!bounds.isEmpty) bounds.width() else drawable.intrinsicWidth
                              val height = if (!bounds.isEmpty) bounds.height() else drawable.intrinsicHeight
                              // Now we check we are > 0
                              val bitmap = Bitmap.createBitmap(if (width <= 0) 1 else width, if (height <= 0) 1 else height,
                                      Bitmap.Config.ARGB_8888)
                              val canvas = Canvas(bitmap)
                              drawable.setBounds(0, 0, canvas.width, canvas.height)
                              drawable.draw(canvas)
                              return bitmap
                          }
                      }
                  }
                  

                  res/layout/activity_main.xml

                  <FrameLayout
                      xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
                      xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
                      android:layout_height="match_parent" tools:context=".MainActivity">
                  
                      <androidx.appcompat.widget.AppCompatImageView
                          android:id="@+id/avatarImageView" android:layout_width="100dp" android:layout_height="100dp"
                          android:layout_gravity="center"/>
                  
                  </FrameLayout>
                  

                  res/drawable/avatar_1.xml

                  <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="128dp" android:height="128dp"
                          android:viewportHeight="128.0" android:viewportWidth="128.0">
                      <path
                          android:fillColor="#FF8A80" android:pathData="M0 0h128v128h-128z"/>
                      <path
                          android:fillColor="#FFE0B2"
                          android:pathData="M36.3 94.8c6.4 7.3 16.2 12.1 27.3 12.4 10.7,-.3 20.3,-4.7 26.7,-11.6l.2.1c-17,-13.3,-12.9,-23.4,-8.5,-28.6 1.3,-1.2 2.8,-2.5 4.4,-3.9l13.1,-11c1.5,-1.2 2.6,-3 2.9,-5.1.6,-4.4,-2.5,-8.4,-6.9,-9.1,-1.5,-.2,-3 0,-4.3.6,-.3,-1.3,-.4,-2.7,-1.6,-3.5,-1.4,-.9,-2.8,-1.7,-4.2,-2.5,-7.1,-3.9,-14.9,-6.6,-23,-7.9,-5.4,-.9,-11,-1.2,-16.1.7,-3.3 1.2,-6.1 3.2,-8.7 5.6,-1.3 1.2,-2.5 2.4,-3.7 3.7l-1.8 1.9c-.3.3,-.5.6,-.8.8,-.1.1,-.2 0,-.4.2.1.2.1.5.1.6,-1,-.3,-2.1,-.4,-3.2,-.2,-4.4.6,-7.5 4.7,-6.9 9.1.3 2.1 1.3 3.8 2.8 5.1l11 9.3c1.8 1.5 3.3 3.8 4.6 5.7 1.5 2.3 2.8 4.9 3.5 7.6 1.7 6.8,-.8 13.4,-5.4 18.4,-.5.6,-1.1 1,-1.4 1.7,-.2.6,-.4 1.3,-.6 2,-.4 1.5,-.5 3.1,-.3 4.6.4 3.1 1.8 6.1 4.1 8.2 3.3 3 8 4 12.4 4.5 5.2.6 10.5.7 15.7.2 4.5,-.4 9.1,-1.2 13,-3.4 5.6,-3.1 9.6,-8.9 10.5,-15.2m-14.4,-49.8c.9 0 1.6.7 1.6 1.6 0 .9,-.7 1.6,-1.6 1.6,-.9 0,-1.6,-.7,-1.6,-1.6,-.1,-.9.7,-1.6 1.6,-1.6zm-25.7 0c.9 0 1.6.7 1.6 1.6 0 .9,-.7 1.6,-1.6 1.6,-.9 0,-1.6,-.7,-1.6,-1.6,-.1,-.9.7,-1.6 1.6,-1.6z"/>
                      <path
                          android:fillColor="#E0F7FA"
                          android:pathData="M105.3 106.1c-.9,-1.3,-1.3,-1.9,-1.3,-1.9l-.2,-.3c-.6,-.9,-1.2,-1.7,-1.9,-2.4,-3.2,-3.5,-7.3,-5.4,-11.4,-5.7 0 0 .1 0 .1.1l-.2,-.1c-6.4 6.9,-16 11.3,-26.7 11.6,-11.2,-.3,-21.1,-5.1,-27.5,-12.6,-.1.2,-.2.4,-.2.5,-3.1.9,-6 2.7,-8.4 5.4l-.2.2s-.5.6,-1.5 1.7c-.9 1.1,-2.2 2.6,-3.7 4.5,-3.1 3.9,-7.2 9.5,-11.7 16.6,-.9 1.4,-1.7 2.8,-2.6 4.3h109.6c-3.4,-7.1,-6.5,-12.8,-8.9,-16.9,-1.5,-2.2,-2.6,-3.8,-3.3,-5z"/>
                      <path
                          android:fillColor="#444" android:pathData="M76.3,47.5 m-2.0, 0 a 2.0,2.0 0 1,1 4.0,0 a2.0,2.0 0 1,1 -4.0,0"/>
                      <path
                          android:fillColor="#444" android:pathData="M50.7,47.6 m-2.0, 0 a 2.0,2.0 0 1,1 4.0,0 a2.0,2.0 0 1,1 -4.0,0"/>
                      <path
                          android:fillColor="#444"
                          android:pathData="M48.1 27.4c4.5 5.9 15.5 12.1 42.4 8.4,-2.2,-6.9,-6.8,-12.6,-12.6,-16.4 17.2 1.5 14.1,-9.4 14.1,-9.4,-1.4 5.5,-11.1 4.4,-11.1 4.4h-18.8c-1.7,-.1,-3.4 0,-5.2.3,-12.8 1.8,-22.6 11.1,-25.7 22.9 10.6,-1.9 15.3,-7.6 16.9,-10.2z"/>
                  </vector>
                  

                  结果:

                  而且,假设你想在它上面添加一个边框,你可以使用这个例子:

                  stroke_drawable.xml

                  <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
                      <stroke
                          android:width="4dp" android:color="@android:color/black"/>
                  </shape>
                  

                  然后将android:foreground="@drawable/stroke_drawable" 添加到布局 XML 文件中的 ImageView 中,你会得到这个:

                  不过,我不确定如何添加阴影(适用于较旧的 Android 版本)。使用FloatingActionButton(来自"com.google.android.material:material" dependency),我未能使位图填充FAB 本身。如果它有效,使用它可能会更好。


                  编辑:如果您希望添加高程阴影(可从 API 21 获得),您可以稍微更改我写的内容:

                  布局 XML 文件内部:

                  <androidx.appcompat.widget.AppCompatImageView android:padding="4dp"
                      android:id="@+id/avatarImageView" android:layout_width="100dp" android:layout_height="100dp" android:elevation="8dp"
                      android:layout_gravity="center" android:background="@drawable/stroke_drawable" tools:srcCompat="@drawable/avatar_1"/>
                  

                  CircularShadowViewOutlineProvider.kt

                  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
                  class CircularShadowViewOutlineProvider : ViewOutlineProvider() {
                      override fun getOutline(view: View, outline: Outline) {
                          val size = Math.max(view.width, view.height)
                          outline.setRoundRect(0, 0, size, size, size / 2f)
                      }
                  }
                  

                  在代码中:

                      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
                          avatarImageView.outlineProvider = CircularShadowViewOutlineProvider()
                  

                  结果:

                  【讨论】:

                    【解决方案23】:

                    我有一个简单的解决方案。 通过右键单击您的包名称并选择新建-> 图像资产来创建一个新的图像资产。 输入名称(任何名称)和路径(系统中图像的位置)。 然后单击下一步并完成。 如果您输入图像名称为“img”,则会在 mipmap 文件夹中自动创建一个名称为“img_round”的圆形图像。

                    然后,这样做:

                    <ImageView
                            android:layout_width="100dp"
                            android:layout_height="100dp"
                            android:src="@mipmap/img_round"/>
                    

                    您的预览可能仍会显示矩形图像。但是,如果您在设备上运行该应用程序,它将是圆形的。

                    【讨论】:

                      【解决方案24】:

                      创建一个 CustomImageview 然后简单地覆盖它的onDraw() 方法如下:

                      @Override
                      protected void onDraw(Canvas canvas) {
                      
                          float radius = this.getHeight()/2;
                          Path path = new Path();
                          RectF rect = new RectF(0, 0, this.getWidth(), this.getHeight());
                          path.addRoundRect(rect, radius, radius, Path.Direction.CW);
                          canvas.clipPath(path);
                          super.onDraw(canvas);
                      
                      }
                      

                      如果您还想要自定义小部件的代码:-

                      CircularImageView.java

                      import android.content.Context;
                      import android.content.res.TypedArray;
                      import android.graphics.Canvas;
                      import android.graphics.Path;
                      import android.graphics.RectF;
                      import android.graphics.drawable.Drawable;
                      import android.util.AttributeSet;
                      import android.widget.ImageView;
                      
                      import androidx.annotation.Nullable;
                      
                      public class CircularImageView extends ImageView {
                      
                          private Drawable image;
                      
                          public CircularImageView(Context context) {
                              super(context);
                      
                              init(null, 0);
                          }
                      
                          public CircularImageView(Context context, @Nullable AttributeSet attrs) {
                              super(context, attrs);
                      
                              init(attrs, 0);
                          }
                      
                          public CircularImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
                              super(context, attrs, defStyleAttr);
                      
                              init(attrs, defStyleAttr);
                          }
                      
                          @Override
                          protected void onDraw(Canvas canvas) {
                      
                              float radius = this.getHeight()/2;
                              Path path = new Path();
                              RectF rect = new RectF(0, 0, this.getWidth(), this.getHeight());
                              path.addRoundRect(rect, radius, radius, Path.Direction.CW);
                              canvas.clipPath(path);
                              super.onDraw(canvas);
                      
                          }
                      
                          private void init(AttributeSet attrs, int defStyle) {
                              TypedArray a = Utils.CONTEXT.getTheme().obtainStyledAttributes(attrs, R.styleable.CircularImageView, 0, 0);
                              try {
                                  image = a.getDrawable(R.styleable.CircularImageView_src);
                              } finally {
                                  a.recycle();
                              }
                      
                              this.setImageDrawable(image);
                          }
                      }
                      

                      另外,将以下代码添加到您的 res/attrs.xml 以创建所需的属性:-

                      <declare-styleable name="CircularImageView">
                              <attr name="src" format="reference" />
                      </declare-styleable>
                      

                      【讨论】:

                      • 这将在 imageview 没有背景时起作用。那该怎么办呢?
                      【解决方案25】:
                      if you want to set edit icon on to circle imageview than put this below code.
                      
                       <FrameLayout
                                      android:layout_width="@dimen/_100sdp"
                                      android:layout_height="@dimen/_100sdp"
                                      android:layout_gravity="center"
                                      android:layout_marginTop="10dp">
                      
                                      <de.hdodenhof.circleimageview.CircleImageView
                                          android:id="@+id/profilePic"
                                          android:layout_width="@dimen/_100sdp"
                                          android:layout_height="@dimen/_100sdp"
                                          android:layout_gravity="bottom|center_horizontal"
                                          android:src="@drawable/ic_upload" />
                      
                                      <de.hdodenhof.circleimageview.CircleImageView
                                          android:id="@+id/iv_camera"
                                          android:layout_width="@dimen/_30sdp"
                                          android:layout_height="@dimen/_30sdp"
                                          android:layout_gravity="top|right"
                                          android:src="@drawable/edit"/>
                                  </FrameLayout>
                      

                      【讨论】:

                        【解决方案26】:

                        如果您希望将图像剪切成圆形显示,那么就可以了

                        public static Bitmap getCircularBitmap(Bitmap bitmap) {
                                Bitmap output;
                        
                                if (bitmap.getWidth() > bitmap.getHeight()) {
                                    output = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
                                } else {
                                    output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getWidth(), Bitmap.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());
                        
                                float r = 0;
                        
                                if (bitmap.getWidth() > bitmap.getHeight()) {
                                    r = bitmap.getHeight() / 2;
                                } else {
                                    r = bitmap.getWidth() / 2;
                                }
                        
                                paint.setAntiAlias(true);
                                canvas.drawARGB(0, 0, 0, 0);
                                paint.setColor(color);
                                canvas.drawCircle(r, r, r, paint);
                                paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
                                canvas.drawBitmap(bitmap, rect, rect, paint);
                                return output;
                            }
                        

                        【讨论】:

                          【解决方案27】:

                          另一个想法是使用ImageViewclipToOutline 属性。

                          这是一个示例布局:

                          <androidx.constraintlayout.widget.ConstraintLayout
                              android:layout_width="match_parent"
                              android:layout_height="match_parent">
                          
                              <!-- Simple view to draw borders for an image,
                                   borders will be rounded because of the oval-shaped background. -->
                              <View
                                  android:id="@+id/v_border"
                                  android:layout_width="50dp"
                                  android:layout_height="50dp"
                                  android:background="@drawable/shape_border"
                                  app:layout_constraintStart_toStartOf="parent"
                                  app:layout_constraintTop_toTopOf="parent" />
                          
                              <!-- Image itself: fits the border view, 
                                   a margin serves as a border width;
                                   the key point here - is a background shape which will clip the view to its forms. -->
                              <ImageView
                                  android:id="@+id/iv_image"
                                  android:layout_width="0dp"
                                  android:layout_height="0dp"
                                  android:layout_margin="4dp"
                                  android:background="@drawable/shape_oval"
                                  android:src="@mipmap/ic_launcher"
                                  app:layout_constraintBottom_toBottomOf="@+id/v_border"
                                  app:layout_constraintEnd_toEndOf="@+id/v_border"
                                  app:layout_constraintStart_toStartOf="@+id/v_border"
                                  app:layout_constraintTop_toTopOf="@+id/v_border" />
                          
                          </androidx.constraintlayout.widget.ConstraintLayout>
                          

                          这是我们的shape_borderdrawable:

                          <?xml version="1.0" encoding="utf-8"?>
                          <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
                              <solid android:color="#FF00FF" />
                          </shape>
                          

                          还有shape_ovaldrawable:

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

                          您应该在代码中做的唯一一件事是启用clipToOutline 属性:

                          binding.ivImage.clipToOutline = true
                          

                          当然你甚至可以用一些BindingAdapter来避免这行代码。

                          【讨论】:

                            【解决方案28】:

                            这是一个比较老的问题,但你可以在drawable文件夹中做一个圆形边框(假设xml文件将被称为circle_border

                            <?xml version="1.0" encoding="utf-8"?>
                            <shape xmlns="http://schemas.android.com/apk/res/android"
                                android:shape="oval">
                            
                                <solid android:color="@android:color/transparent" />
                            
                                <!-- If you want a padding -->
                                <padding android:top="4dp" android:left="4dp" android:right="4dp" android:bottom="4dp" />
                            
                                <!-- If you want the circle border to have a color -->
                                <strong android:width="1dp" android:color="#FFFFFF" />
                            
                            </shape>
                            

                            然后就可以把它作为ImageView的背景了

                            <ImageView
                                android:background="@drawable/circle_border"
                                <!-- other attributes here -->
                            />
                            

                            【讨论】:

                            • 这会在图像后面画一个圆圈,但不会把它剪成圆形。
                            【解决方案29】:

                            只需使用这个简单的代码: 首先添加依赖:

                            implementation 'de.hdodenhof:circleimageview:2.2.0'
                            

                            然后在xml布局中添加以下代码:-

                            <de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto"
                                                                    android:id="@+id/Imgshaligram"
                                                                    android:layout_width="96dp"
                                                                    android:layout_height="96dp"
                                                                    android:src="@drawable/shaligram"
                                                                    app:civ_border_color="#d1b1b1"
                            
                                                                    android:foregroundGravity="center"/>
                            

                            【讨论】:

                              【解决方案30】:

                              另外,这两个库可以帮助您。

                              https://github.com/vinc3m1/RoundedImageView

                              实现以下代码:

                              implementation 'com.makeramen:roundedimageview:2.3.0'
                              

                              简单用法:

                              <com.makeramen.roundedimageview.RoundedImageView
                                      xmlns:app="http://schemas.android.com/apk/res-auto"
                                      android:id="@+id/imageView1"
                                      android:src="@drawable/photo1"
                                      android:scaleType="fitCenter"
                                      app:riv_corner_radius="30dip"
                                      app:riv_border_width="2dip"
                                      app:riv_border_color="#333333"
                                      app:riv_mutate_background="true"
                                      app:riv_tile_mode="repeat"
                                      app:riv_oval="true" />
                              

                              https://github.com/chirag-kachhadiya/RoundedImageView

                              简单用法:

                              实现以下代码:

                              implementation 'com.github.chirag-kachhadiya:RoundedImageView:1.0'
                              
                              
                              
                               <com.infinityandroid.roundedimageview.RoundedImageView
                                              android:layout_width="150dp"
                                              android:layout_height="wrap_content"
                                              android:layout_margin="10dp"
                                              android:adjustViewBounds="true"
                                              android:src="@drawable/the_hundred"
                                              app:corner_radius="10" />
                              

                              【讨论】:

                                猜你喜欢
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2020-07-26
                                • 2017-04-27
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                相关资源
                                最近更新 更多