【问题标题】:Set Round Corner image in ImageView在 ImageView 中设置圆角图像
【发布时间】:2015-10-18 22:57:30
【问题描述】:

我在网站上搜索了更多,并得到了很多如下建议

  • 使用自定义样式更改背景以设置角半径和填充(将图像获取为矩形,将背景获取为圆角)

  • 通过解码图像将给定图像更改为位图,并通过传递此位图和宽度来裁剪功能(加载需要更多时间)

我已经检查了WhatsApp Chat history list and it has rounded corner images but its loaded with minimum time

您能否建议我使用 WhatsApp 中的圆形图像创建列表视图模板的最佳方法?

我希望通过在 xml 页面中设置样式详细信息来更改带有圆角的图像。 (图像宽度和高度为 60 dp,我的列表视图也有大约 60 个项目)

参考资料:

res/mylayout.xml:

<ImageView
        android:id="@+id/contactssnap"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/contactssnap"
        android:background="@drawable/roundimage" />

res/drawable/roundimage.xml:

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <solid android:color="#ffffffff" />
    <stroke
        android:width="2dp"
        android:color="#90a4ae" />
    <size
        android:height="50dp"
        android:width="50dp" />
    <padding
        android:bottom="2dp"
        android:left="2dp"
        android:right="2dp"
        android:top="2dp" />
    <corners android:radius="100dp" />
</shape>

注意:支持的 Android 版本从 14 到 22

【问题讨论】:

  • 你是如何设置 ImageView 的?从资源还是从其他地方下载位图?
  • stackover flow 已经有了答案,请参考这个stackoverflow.com/questions/2459916/…
  • @bGorle: 是的,我试过了,加载图片需要更多时间
  • 使用android.support.v4.graphics.drawable.RoundedBitmapDrawable
  • 检查这个现在我们有ShapeableImageView来制作圆形或圆形的imageView stackoverflow.com/a/61086632/7666442

标签: android android-listview android-imageview android-xml


【解决方案1】:

材质组件库提供了新的 ShapeableImageView
只需使用如下布局:

  <com.google.android.material.imageview.ShapeableImageView
      ...
      app:shapeAppearanceOverlay="@style/roundedCorners"
      app:srcCompat="@drawable/...." />

使用 shapeAppearanceOverlay 属性,您可以应用自定义形状,在本例中为圆角:

  <style name="roundedCorners" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">xxdp</item>
  </style>

*注意:至少需要1.2.0-alpha03版本。

【讨论】:

  • 这是我见过的最优雅的方式之一,也非常适用于毕加索错误/占位符!
【解决方案2】:

sats 的答案是有效的。但是 RoundedBitmapDrawable 不能应用于具有 scaleType: centerCrop 的 ImageView。

更新了。

如果您使用的是级别 21 的 Android API。我们在这里有一个简单的解决方案。

1st,创建drawable作为imageview的背景

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="8dp" />
<solid android:color="@android:color/white" />

<stroke
    android:width="1dp"
    android:color="@color/colorWhite" />
</shape>

接下来,将 ImageView 的属性 setClipToOutline 更改为 true。并将圆角drawable设置为ImageView的背景。

就是这样。

在我的演示中,我将这种方法用于圆形图像视图。可以在这里找到cuberto's dialog

【讨论】:

【解决方案3】:

将 imageView 放入 CardView 并为 CardView 设置 CornerRadius

<android.support.v7.widget.CardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:cardCornerRadius="8dp"
        app:cardElevation="0dp">

        <ImageView
            android:id="@+id/imgTourismHr"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scaleType="fitXY" />

    </android.support.v7.widget.CardView>

【讨论】:

【解决方案4】:

您可以使用 Google 提供的标准 API 创建圆形 ImageView。

ImageView imageView = (ImageView) findViewById(R.id.circleImageView);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image);
RoundedBitmapDrawable roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
roundedBitmapDrawable.setCircular(true);
imageView.setImageDrawable(roundedBitmapDrawable);

另请参阅https://www.youtube.com/watch?v=zVC-YAnDlgk

【讨论】:

  • 感谢这看起来对我有用,但我遇到的唯一问题是decodeResource 的第二个参数。我有一个加载图像的imageUrl。在这种情况下我该如何实现?
【解决方案5】:

See the rounded rectangle image Output with Rounded Corner border

现在设置带圆角边框的圆角矩形图像。

您可以使用 app:cardCornerRadius="30dp"app:cardUseCompatPadding="true" 在 CardView 中简单声明 CardView app:cardElevation="0dp"

查看下面的 Xml 代码

            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center"
                app:cardCornerRadius="30dp"
                app:cardUseCompatPadding="true"
                app:cardElevation="0dp"
                android:layout_margin="5dp"
                >
                <ImageView
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:src="@drawable/temp"
                    android:scaleType="fitXY"
                    android:layout_gravity="center"
                    />
            </androidx.cardview.widget.CardView>
        </androidx.cardview.widget.CardView>

【讨论】:

    【解决方案6】:

    根据需要更改 cardCornerRadius

    <androidx.cardview.widget.CardView
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:layout_gravity="center"
        app:cardCornerRadius="20dp">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/sample"
                android:scaleType="centerCrop"/>
    
        </LinearLayout>
    </androidx.cardview.widget.CardView>
    

    【讨论】:

      【解决方案7】:

      我们可以使用 androidx 提供的 CardView 小部件来解决这个问题。

      代码如下。

      <RelativeLayout
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content">
                      <LinearLayout
                          android:id="@+id/avatar_layout"
                          android:layout_width="wrap_content"
                          android:layout_height="wrap_content"
                          android:layout_marginBottom="@dimen/padding_20"
                          android:background="@drawable/roundimage">
      
                          <androidx.cardview.widget.CardView
                              android:layout_width="wrap_content"
                              android:layout_height="wrap_content"
                              android:orientation="vertical"
                              app:cardCornerRadius="50dp"
                              app:cardElevation="0dp">
      
                              <ImageView
                                  android:id="@+id/avatar"
                                  android:layout_width="100dp"
                                  android:layout_height="100dp"
                                  android:padding="@dimen/padding_5"
                                  android:scaleType="fitXY"
                                  android:src="@drawable/launch_icon" />
      
                          </androidx.cardview.widget.CardView>
                      </LinearLayout>
      
                      <ImageView
                          android:id="@+id/avatar_edit"
                          android:layout_width="@dimen/padding_30"
                          android:layout_height="@dimen/padding_30"
                          android:src="@drawable/edit_profile_btn"
                          android:clickable="true"
                          android:layout_alignEnd="@id/avatar_layout"/>
      </RelativeLayout>
      

      【讨论】:

        【解决方案8】:

        你检查过android中的9补丁技术了吗?

        如果您正在尝试创建带有圆角的应用程序气泡聊天,我建议您使用这种技术而不是使用 XML 位图解码器。

        这里是一个例子:Link

        根据这个示例,您可以使用 9 个补丁生成器来创建您自己的自定义形状和位图图像,它们会自动调整大小以适应视图内容和屏幕大小。图像的选定部分在图像中绘制的基于水平或垂直的指标进行缩放。

        【讨论】:

          【解决方案9】:

          kotlin 解决方案:

          class RoundedCornerImageView(context: Context?, attrs: AttributeSet?) : 
          androidx.appcompat.widget.AppCompatImageView(context, attrs) {
          
          private val path: Path? = Path()
          private var cornerRadius: Int = 0
          private var roundedCorner: Int = 0
          
          init {
              val a: TypedArray = context!!.obtainStyledAttributes(attrs, R.styleable.RoundedCornerImageView)
              cornerRadius = a.getDimensionPixelSize(R.styleable.RoundedCornerImageView_radius, 0)
              roundedCorner = a.getInt(R.styleable.RoundedCornerImageView_corner, 0)
              a.recycle()
          }
          
          override fun onDraw(canvas: Canvas?) {
              if (!path!!.isEmpty){
                  canvas!!.clipPath(path)
              }
              super.onDraw(canvas)
          }
          
          override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
              super.onSizeChanged(w, h, oldw, oldh)
              setPath()
          }
          
          private fun setPath() {
              path!!.rewind()
          
              val radii = FloatArray(8)
          
              Log.d(TAG, "setPath : $roundedCorner")
          
              when(roundedCorner){
                  0 ->{
                      // all side
                      for(i in 0 until 8)
                          radii[i] = cornerRadius.toFloat()
                  }
          
                  1 ->{
                      //top left
                      radii[0] = cornerRadius.toFloat()
                      radii[1] = cornerRadius.toFloat()
                  }
          
                  2 ->{
                      //top right
                      radii[2] = cornerRadius.toFloat()
                      radii[3] = cornerRadius.toFloat()
                  }
          
                  3 ->{
                      //bottom right
                      radii[4] = cornerRadius.toFloat()
                      radii[5] = cornerRadius.toFloat()
          
                  }
          
                  4 ->{
                      //bottom left
                      radii[6] = cornerRadius.toFloat()
                      radii[7] = cornerRadius.toFloat()
          
                  }
          
                  5 ->{
                      //left
                      radii[0] = cornerRadius.toFloat()
                      radii[1] = cornerRadius.toFloat()
                      radii[6] = cornerRadius.toFloat()
                      radii[7] = cornerRadius.toFloat()
          
                  }
          
                  6 ->{
                      //right
                      radii[2] = cornerRadius.toFloat()
                      radii[3] = cornerRadius.toFloat()
                      radii[4] = cornerRadius.toFloat()
                      radii[5] = cornerRadius.toFloat()
          
                  }
          
                  7 ->{
                      //top
                      radii[0] = cornerRadius.toFloat()
                      radii[1] = cornerRadius.toFloat()
                      radii[2] = cornerRadius.toFloat()
                      radii[3] = cornerRadius.toFloat()
          
                  }
          
                  8 ->{
                      //bottom
                      radii[4] = cornerRadius.toFloat()
                      radii[5] = cornerRadius.toFloat()
                      radii[6] = cornerRadius.toFloat()
                      radii[7] = cornerRadius.toFloat()
          
                  }
              }  
              path.addRoundRect(RectF(0F,0F,width.toFloat(),
                                height.toFloat()),
                                radii,Path.Direction.CW)
          }
          

          }

          不要忘记在 attr.xml 文件中添加它

          <declare-styleable name="RoundedCornerImageView">
              <attr name="radius" format="dimension"/>
              <attr name="corner">
                 <flag name="topLeft" value="1"/>
                 <flag name="topRight" value="2"/>
                 <flag name="bottomRight" value="3"/>
                 <flag name="bottomLeft" value="4"/>
                 <flag name="left" value="5"/>
                 <flag name="right" value="6"/>
                 <flag name="top" value="7"/>
                 <flag name="bottom" value="8"/>
              </attr>
          </declare-styleable> 
          

          【讨论】:

            【解决方案10】:

            使用 Glide 加载网络图像的任何人的快速解决方案,它使用 RequestOptions.circleCropTransform():

            Glide.with(context)
                 .load(imageUrl)
                 .apply(RequestOptions.circleCropTransform())
                 .into(object : CustomViewTarget<ImageView, Drawable>(imageView) {
                        override fun onLoadFailed(errorDrawable: Drawable?) {
                        }
                        override fun onResourceCleared(placeholder: Drawable?) {
                        }
                        override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
                            imageView.setImageDrawable(resource)
                        }
                    })
            

            【讨论】:

              【解决方案11】:

              只需将android:padding="5pt"添加到您的 xml 布局中,例如

               <ImageView
                          android:id="@+id/ivGadgetImage"
                          android:layout_width="50pt"
                          android:layout_height="50pt"
                          android:padding="5pt"
                          tools:srcCompat="@tools:sample/avatars" />

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2018-12-10
                • 2013-08-16
                • 1970-01-01
                • 1970-01-01
                • 2014-09-13
                • 2013-01-24
                相关资源
                最近更新 更多