Android经典实战之Kotlin中实现圆角图片和圆形图片

简介: 本文介绍两种实现圆角图像视图的方法。第一种是通过自定义Kotlin `AppCompatImageView`,重写`onDraw`方法使用`Canvas`和`Path`进行圆角剪裁。第二种利用Android Material库中的`ShapeableImageView`,简单配置即可实现圆角效果。两种方法均易于实现且提供动态调整圆角半径的功能。

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点

实现圆角是一个很常见的需求,也有很多种方式,这里介绍2种,实现起来都不麻烦,很方便

方法一:自定义View

在 Kotlin 中实现圆角的 AppCompatImageView 可以通过自定义控件和使用 CanvasPath 进行剪裁来实现。下面是一个简单的实现方法,继承 AppCompatImageView 并自定义绘制方法,使其可以设置圆角属性。

自定义 AppCompatImageView

首先,创建一个自定义的 AppCompatImageView 类:

import android.content.Context
import android.graphics.Canvas
import android.graphics.Path
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatImageView
import kotlin.math.min

class RoundedImageView @JvmOverloads constructor(
    context: Context, 
    attrs: AttributeSet? = null, 
    defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr) {

    private val path = Path()
    private var cornerRadius = 0f

    init {
        // 初始化代码,可以在此读取自定义属性
    }

    override fun onDraw(canvas: Canvas) {
        val rect = canvas.clipBounds
        val radius = min(rect.width(), rect.height()) / 2f
        path.addRoundRect(
            rect.left.toFloat(), rect.top.toFloat(), rect.right.toFloat(), rect.bottom.toFloat(),
            floatArrayOf(cornerRadius, cornerRadius, cornerRadius, cornerRadius, 
                         cornerRadius, cornerRadius, cornerRadius, cornerRadius), 
            Path.Direction.CW
        )
        canvas.clipPath(path)
        super.onDraw(canvas)
    }

    // 设置圆角半径
    fun setCornerRadius(radius: Float) {
        cornerRadius = radius
        invalidate()
    }
}

在布局文件中使用自定义的 ImageView

在 XML 布局文件中使用自定义的 RoundedImageView

<com.example.yourpackage.RoundedImageView
    android:id="@+id/rounded_image_view"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:scaleType="centerCrop"
    android:src="@drawable/your_image"
    />

在代码中动态设置圆角

最后,在代码中动态设置圆角:

val roundedImageView = findViewById<RoundedImageView>(R.id.rounded_image_view)
roundedImageView.setCornerRadius(30f) // 设置圆角半径为30像素

完整实现

将这个方案分成两个主要部分:

1、 创建一个自定义的 RoundedImageView 类,并在 onDraw 方法中重写绘制逻辑。
2、 使用自定义的 RoundedImageView 并动态设置圆角。

通过这种方式,可以实现一个自定义的 AppCompatImageView,能够根据需要动态调整圆角半径。同时,也可以进一步扩展这个自定义控件,例如支持设置不同角的圆角半径,这取决于实际的需求和设计要求。

方法二:ShapeableImageView

另一个常用的方法是使用 ShapeableImageView 以及 material 库提供的功能,它提供了一些方便的属性来实现圆角效果。

使用 ShapeableImageView

ShapeableImageView 是 Android Material 库的一部分,可以非常方便地实现圆角和其他形状效果。

添加依赖

首先,在 build.gradle 文件中添加 Material 依赖:

dependencies {
   
    implementation 'com.google.android.material:material:1.9.0' // 确保使用最新版本
}

在布局文件中使用 ShapeableImageView

在 XML 布局文件中使用 ShapeableImageView 并设置圆角属性:

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/rounded_image_view"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:scaleType="centerCrop"
    android:src="@drawable/your_image"
    app:shapeAppearanceOverlay="@style/RoundedImageViewStyle"/>

定义样式

res/values/styles.xml 中定义一个样式,用于设置 ShapeableImageView 的圆角:

<resources>
    <style name="RoundedImageViewStyle" parent="">
        <item name="cornerFamily">rounded</item>
        <item name="cornerSize">16dp</item>
    </style>
</resources>

动态设置圆角半径

在代码中,你还可以动态地设置圆角半径:

import com.google.android.material.shape.CornerFamily
import com.google.android.material.imageview.ShapeableImageView

val roundedImageView = findViewById<ShapeableImageView>(R.id.rounded_image_view)
val shapeAppearanceModel = roundedImageView.shapeAppearanceModel.toBuilder()
    .setAllCorners(CornerFamily.ROUNDED, 30f) // 设置所有圆角半径为 30px
    .build()
roundedImageView.shapeAppearanceModel = shapeAppearanceModel

这种方法利用了 Material Design 提供的现成功能,可以更轻松地应用和管理圆角效果,而无需自己实现复杂的绘制逻辑。

完整实现

将这两个部分结合起来:

1、 在 build.gradle 中添加 Material 依赖。
2、 在布局文件中使用 ShapeableImageView 并设置初始的圆角样式。
3、 在代码中动态调整圆角半径。

这样,你可以获得一个易于管理且高度可控的圆角 ImageView,同时也利用了 Material Design 的强大功能。此外,ShapeableImageView 还支持其他形状和效果,可以根据需要进一步扩展。


欢迎关注我的公众号AntDream查看更多精彩文章!

目录
相关文章
|
3月前
|
存储 消息中间件 人工智能
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
123 3
|
2月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
283 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
2月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
232 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
2月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
571 4
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
3月前
|
存储 消息中间件 人工智能
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
248 10
【08】AI辅助编程完整的安卓二次商业实战-修改消息聊天框背景色-触发聊天让程序异常终止bug牵涉更多聊天消息发送优化处理-优雅草卓伊凡
|
3月前
|
存储 消息中间件 人工智能
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
115 11
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
|
2月前
|
移动开发 Android开发
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【03】建立隐私关于等相关页面和内容-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
142 0
|
3月前
|
XML 存储 Java
【06】AI辅助编程完整的安卓二次商业实战-背景布局变更增加背景-二开发现页面跳转逻辑-替换剩余图标-优雅草卓伊凡
【06】AI辅助编程完整的安卓二次商业实战-背景布局变更增加背景-二开发现页面跳转逻辑-替换剩余图标-优雅草卓伊凡
109 3
【06】AI辅助编程完整的安卓二次商业实战-背景布局变更增加背景-二开发现页面跳转逻辑-替换剩余图标-优雅草卓伊凡
|
3月前
|
存储 消息中间件 人工智能
【04】AI辅助编程完整的安卓二次商业实战-寻找修改替换新UI首页图标-菜单图标-消息列表图标-优雅草伊凡
【04】AI辅助编程完整的安卓二次商业实战-寻找修改替换新UI首页图标-菜单图标-消息列表图标-优雅草伊凡
142 4
|
3月前
|
XML 编解码 Android开发
非常经典的Android开发问题-mipmap图标目录和drawable图标目录的区别和适用场景实战举例-优雅草卓伊凡
非常经典的Android开发问题-mipmap图标目录和drawable图标目录的区别和适用场景实战举例-优雅草卓伊凡
219 0
非常经典的Android开发问题-mipmap图标目录和drawable图标目录的区别和适用场景实战举例-优雅草卓伊凡