Material ShapeableImageView 使用详解

Material Design 系列

  1. Material Design UI方案使用讲解
  2. Material TextInputLayout使用详解
  3. Material ShapeableImageView 使用详解

博客创建时间:2022.08.23
博客更新时间:2023.05.07

以Android studio build=7.0.0,SDKVersion 31来分析讲解。如图文和网上其他资料不一致,可能是别的资料版本较低而已。


前言

继承自ImageView,可以为image添加描边大小、颜色,以及圆角、裁切等,这得益于它新增了一个属性shapeAppearance,具体实现在ShapeAppearanceModel,可以通过style来配置,也可以通过代码实现。
在这里插入图片描述

属性&方法

在这里插入图片描述
首先可以看出它是继承于AppCompatImageView的,它的特性设置一般保存在ShapeAppearanceModel中。实际它的属性值都是保存在ShapeAppearanceModel中的。

属性说明参数及含义
shapeAppearanceShapeableImageView的形状外观样式
shapeAppearanceOverlayShapeableImageView的形状外观叠加样式
strokeColor描边颜色
strokeWidth描边宽度
cornerFamily四个角shape属性/样式-rounded: 圆角0、-cut: 切角1
cornerSize四个角弧度可以是具体DP,也可以是%,以控件高为准
cornerFamilyTopLeft左上shape属性/样式-rounded: 圆角0、-cut: 切角1
cornerFamilyTopRight右上shape属性/样式-rounded: 圆角0、-cut: 切角1
cornerFamilyBottomRight右下shape属性/样式-rounded: 圆角0、-cut: 切角1
cornerFamilyBottomLeft左下shape属性/样式-rounded: 圆角0、-cut: 切角1
cornerSizeTopLeft左上弧度
cornerSizeTopRight右上弧度
cornerSizeBottomRight右下弧度
cornerSizeBottomLeft左下弧度

样式控制

ShapeableImageView 的样式只要由shapeAppearanceOverlay或shapeAppearance控制。

ShapeableImageView本质是通过ViewOutlineProvider实现剪裁的。ViewOutlineProvider的效率比传统的Xfermode进行剪裁的方式高很多。

        <!-- 圆角图片 -->
        <!-- shapeAppearanceOverlay或shapeAppearance 加载style -->
        <!-- strokeColo描边颜色 -->
        <!-- strokeWidth描边宽度 -->
        <com.google.android.material.imageview.ShapeableImageView
        android:id="@+id/image1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:padding="1dp"
        android:src="@mipmap/home3"
        app:shapeAppearanceOverlay="@style/roundedCornerImageStyle"
        app:strokeColor="#F44336"
        app:strokeWidth="2dp" />

1. 圆形图

    <!-- 圆形图片 -->
    <style name="circleImageStyle">
        <item name="cornerFamily">rounded</item>
        <item name="cornerSize">50%</item>
    </style>

2、 菱形

  <!-- 菱形图片 -->
    <style name="diamondImageStyle">
        <item name="cornerFamily">cut</item>
        <item name="cornerSize">50%</item>
    </style>

3. 水滴形

    <!-- 水滴 -->
    <style name="waterImageStyle">
        <item name="cornerFamilyBottomLeft">rounded</item>
        <item name="cornerFamilyBottomRight">rounded</item>
        <item name="cornerFamilyTopLeft">rounded</item>
        <item name="cornerFamilyTopRight">rounded</item>
        <item name="cornerSizeBottomLeft">25dp</item>
        <item name="cornerSizeBottomRight">25dp</item>
        <item name="cornerSizeTopLeft">70%</item>
        <item name="cornerSizeTopRight">70%</item>
    </style>

4. 火箭头

    <!-- 火箭头图片 -->
    <style name="rocketImageStyle">
        <item name="cornerFamilyTopLeft">rounded</item>
        <item name="cornerFamilyTopRight">rounded</item>
        <item name="cornerSizeTopLeft">70%</item>
        <item name="cornerSizeTopRight">70%</item>
    </style>

5. 叶子形

    <!-- 叶子图片 -->
    <style name="leafImageStyle">
        <item name="cornerFamilyTopLeft">rounded</item>
        <item name="cornerFamilyBottomRight">rounded</item>
        <item name="cornerSizeTopLeft">70%</item>
        <item name="cornerSizeBottomRight">70%</item>
    </style>

6. 八角形

    <!-- 切角图片 -->
    <style name="cutImageStyle">
        <item name="cornerFamily">cut</item>
        <item name="cornerSize">28%</item>
    </style>

7. 圆角

    <!-- 圆角图片 -->
    <style name="roundedCornerImageStyle">
        <item name="cornerFamily">rounded</item>
        <!--  可以是具体的Dp-->
          <item name="cornerSize">25dp</item>
        <!--  也可以是%,以高为基准-->
<!--        <item name="cornerSize">15%</item>-->
    </style>

8. tip形

    <!-- tip图片 -->
    <style name="tipImageStyle">
        <item name="cornerFamilyTopLeft">rounded</item>
        <item name="cornerSizeTopLeft">50%</item>
        <item name="cornerFamilyBottomLeft">rounded</item>
        <item name="cornerSizeBottomLeft">50%</item>

        <item name="cornerFamilyTopRight">cut</item>
        <item name="cornerSizeTopRight">50%</item>
        <item name="cornerFamilyBottomRight">cut</item>
        <item name="cornerSizeBottomRight">50%</item>
    </style>

    <!--ShapeableImageView 半圆 -->
    <style name="SemicircleStyle">
        <item name="cornerFamily">rounded</item>
        <item name="cornerSizeTopLeft">50%</item>
        <item name="cornerSizeTopRight">50%</item>
    </style>

    <!--ShapeableImageView 六边形 -->
    <style name="HexagonStyle">
        <item name="cornerFamily">cut</item>
        <item name="cornerSizeTopLeft">50%</item>
        <item name="cornerSizeTopRight">50%</item>
        <item name="cornerSizeBottomLeft">50%</item>
        <item name="cornerSizeBottomRight">50%</item>
    </style>

9.代码控制

  mBinding.roundedImage.shapeAppearanceModel = ShapeAppearanceModel.builder()
            .setAllCorners(CornerFamily.ROUNDED, 60f)// 设置圆角
                .build()
        mBinding.cutImage.shapeAppearanceModel = ShapeAppearanceModel.builder()
                .setTopLeftCorner(CornerFamily.CUT, RelativeCornerSize(0.4f))//设置指定方向圆角
                .setTopRightCorner(CornerFamily.CUT, RelativeCornerSize(0.4f))//设置指定方向圆角
                .setBottomRightCorner(CornerFamily.CUT, RelativeCornerSize(0.3f))//设置指定方向圆角
                .setBottomLeftCorner(CornerFamily.CUT, RelativeCornerSize(0.3f))//设置指定方向圆角
                .build()


        mBinding.randomImage.shapeAppearanceModel = ShapeAppearanceModel.builder()
            .setAllCornerSizes(ShapeAppearanceModel.PILL)
            .setTopLeftCornerSize(100f)//设置指定方向圆角大小
            .setTopRightCornerSize(RelativeCornerSize(0.5f))//设置指定方向圆角大小
            .setBottomLeftCornerSize(20f)//设置指定方向圆角大小
            .setBottomRightCornerSize(AbsoluteCornerSize(50f))//设置指定方向圆角大小
            .build()


        //绘制圆角
        mBinding.roundedImage1.apply {
            outlineProvider = object : ViewOutlineProvider() {
                override fun getOutline(view: View, outline: Outline) {
                    outline.setRoundRect(0, 0, view.width, view.height, 80f)
                }
            }
            clipToOutline = true
        }
        //绘制圆形
        mBinding.cutImage2.apply {
            outlineProvider = object : ViewOutlineProvider() {
                override fun getOutline(view: View, outline: Outline) {
                    outline.setOval(0, 0, view.width, view.width)
                }
            }
            clipToOutline = true
        }

        mBinding.randomImage2.apply {
            outlineProvider = object : ViewOutlineProvider() {
                override fun getOutline(view: View, outline: Outline) {
                    view.elevation = 10F
                    val gap = 20F
                    val path = Path()
                    path.moveTo(-gap, -gap)
                    path.lineTo(-gap, view.measuredHeight.toFloat() + gap) //左下点
                    path.lineTo(
                        (view.measuredWidth / 2).toFloat(),
                        (view.measuredHeight + 50).toFloat()
                    )
                    path.lineTo(
                        view.measuredWidth.toFloat() + gap,
                        view.measuredHeight.toFloat() + gap
                    )
                    path.lineTo(view.measuredWidth.toFloat() + gap, -gap) //右上点
                    path.close()
                    outline.setConvexPath(path)
                    view.scaleX = 0.5F
                    view.scaleY = 0.5F
                }
            }
        }



关于Stroke

ShapeableImageView指定strokeWidth描边的时候,其描边会被覆盖掉一半,如strokeWidth=4dp,上下左右会被覆盖,实际的效果是只有2dp被显示。
在这里插入图片描述
ShapeableImageView指定strokeWidth描边的时候,没有设置padding,那笔画可能一半看不见,需要设置padding, 设置描边的时候,需要添加padding属性,padding的值为strokeWidth的一半。


总结

有兴趣可以查看源码源码Demo:https://gitee.com/luofaxin/CodeAanalysis.git
在这里插入图片描述


相关链接

  1. Material Design UI方案使用讲解
  2. Material TextInputLayout使用详解
  3. Material ShapeableImageView 使用详解

扩展链接:

  1. 强大无匹的自定义下拉列表
  2. Lottie动画 轻松使用
  3. PNG、JPG等普通图片高保真转SVG图
  4. Android 完美的蒙层方案

博客书写不易,您的点赞收藏是我前进的动力,千万别忘记点赞、 收藏 ^ _ ^ !

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值