百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

3D边框效果绝了Jetpack Compose也太会玩了吧

zhezhongyun 2025-08-01 22:13 4 浏览

在Jetpack Compose中创建惊艳的3D边框效果

大家好!今天我要分享一个超酷的技巧——如何在Jetpack Compose中创建 3D边框效果 。这种效果可以应用于任何视图和任何形状,我们还会用它来打造一个 漂亮的搜索框 。让我们开始吧!

凸起边框效果

首先,我们定义一个 convexBorder 扩展函数,用于在 Modifier 上绘制凸起边框。

ConvexStyle类

为了更清晰地表示边框的凸起效果样式,我们先创建一个 ConvexStyle 数据类:

data class ConvexStyle(    val blur: Dp = 3.dp,    val offset: Dp = 2.dp,    val glareColor: Color = Color.White.copy(0.64f),    val shadowColor: Color = Color.Black.copy(0.64f)

主函数定义

现在我们可以定义主函数了:

fun Modifier.convexBorder(    color: Color,    shape: Shape,    strokeWidth: Dp = 8.dp,    convexStyle: ConvexStyle = ConvexStyle())

参数说明:

  • color - 边框颜色
  • shape - 边框形状
  • strokeWidth - 边框宽度
  • convexStyle - 应用于边框的凸起效果样式

实现细节

绘制阴影和高光

在实现 convexBorder 函数之前,我们需要定义一个辅助函数 drawConvexBorderShadow ,用于绘制创建凸起效果的阴影。

fun DrawScope.drawConvexBorderShadow(    outline: Outline,    strokeWidth: Dp,    blur: Dp,    offsetX: Dp,    offsetY: Dp,    shadowColor: Color) = drawIntoCanvas { canvas ->    // 创建并设置Paint对象    val shadowPaint = Paint().apply {        this.style = PaintingStyle.Stroke        this.color = shadowColor        this.strokeWidth = strokeWidth.toPx()    }        // 保存当前图层    canvas.saveLayer(size.toRect(), shadowPaint)        val halfStrokeWidth = strokeWidth.toPx() / 2    // 平移画布以适应边界    canvas.translate(halfStrokeWidth, halfStrokeWidth)    // 绘制阴影轮廓    canvas.drawOutline(outline, shadowPaint)        // 应用混合模式和模糊效果    shadowPaint.asFrameworkPaint().apply {        xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OUT)        maskFilter = BlurMaskFilter(blur.toPx(), BlurMaskFilter.Blur.NORMAL)    }        // 设置裁剪颜色    shadowPaint.color = Color.Black    // 平移画布并绘制阴影裁剪轮廓    canvas.translate(offsetX.toPx(), offsetY.toPx())    canvas.drawOutline(outline, shadowPaint)    // 恢复画布原始状态    canvas.restore()}

convexBorder实现

有了 drawConvexBorderShadow 函数,我们现在可以定义主函数来绘制凸起边框了。

fun Modifier.convexBorder(    /* 参数... */) = this.drawWithContent {    // 调整大小以适应画布边界    val adjustedSize = Size(size.width - strokeWidth.toPx(), size.height - strokeWidth.toPx())    // 根据形状和调整后的大小创建轮廓    val outline = shape.createOutline(adjustedSize, layoutDirection, this)        // 绘制可组合内容的原始内容    drawContent()        // 平移画布以适应边界    translate(halfStrokeWidth, halfStrokeWidth) {        // 绘制主边框轮廓        drawOutline(            outline = outline,            color = color,            style = Stroke(width = strokeWidth.toPx())        )    }        with(convexStyle) {        // 绘制阴影轮廓        drawConvexBorderShadow(outline, strokeWidth, blur, -offset, -offset, shadowColor)        // 绘制高光轮廓        drawConvexBorderShadow(outline, strokeWidth, blur, offset, offset, glareColor)    }}

恭喜你!我们已经成功实现了3D边框效果。现在,让我们看看如何利用这个函数创建一个漂亮的搜索框。

实战示例

让我们进入今天的实战部分。要编写一个自定义样式的 TextField ,我们可以利用 BasicTextField decorationBox 参数。

// 保存文本输入的可变状态var text by remember { mutableStateOf("") }BasicTextField(    value = text,    onValueChange = { text = it },    singleLine = true,    keyboardOptions = KeyboardOptions(        capitalization = KeyboardCapitalization.Sentences,        imeAction = ImeAction.Search    ),    textStyle = LocalTextStyle.current.copy(        fontSize = 16.sp,        fontWeight = FontWeight.Medium    ),    decorationBox = { innerTextField ->        Row(            modifier = Modifier                .size(350.dp, 60.dp)                // 设置背景颜色和形状                .background(Color(0xFF7F2DBF), CircleShape)                // 应用相同颜色和形状的凸起边框                .convexBorder(Color(0xFF7F2DBF), CircleShape)                .padding(horizontal = 20.dp),            verticalAlignment = Alignment.CenterVertically,            horizontalArrangement = Arrangement.spacedBy(8.dp)        ) {            // 添加搜索图标            Icon(                imageVector = Icons.Rounded.Search,                contentDescription = null            )            Box {                // 当输入文本为空时显示占位符                if (text.isEmpty()) {                    Text(                        text = "Search...",                        style = LocalTextStyle.current.copy(color = Color(0xFF242424))                    )                }                // 显示实际的文本字段                innerTextField()            }        }    })

最终效果

感谢 阅读这篇文章! 如果你觉得它 有趣 有价值 ,请点击点赞并关注获取更多精彩内容

相关推荐

3D边框效果绝了Jetpack Compose也太会玩了吧

在JetpackCompose中创建惊艳的3D边框效果大家好!今天我要分享一个超酷的技巧——如何在JetpackCompose中创建3D边框效果。这种效果可以应用于任何视图和任何形状...

“雨”你同行,他们在岗位上为您守护……

7月10日京津冀地区迎来降雨天气京铁人以“降雨预警”为令迎风而上逆水而行全力守护铁路运输安全雨帘下的“摆渡人”北京站、石家庄站及时铺设防滑垫,检查排水设施,确保旅客行走通道安全。北京北站加密站台巡视...

战士实用小福利!巧用宏命令让血条更直观

很多战士朋友经常被怒气和血条所困扰,如何及时的进行规避开启防御技能?如何更好的利用怒气打出伤害?成为了众多战士的首要问题。现在即使在没有插件的支持下我们也可以实现这样的功能,巧用宏命令就可以让怒气和血...

python操作word 添加导航栏,导航栏在左边显示

点赞标记,明天就能用上这几个技巧!要实现Python生成Word文档并显示左侧导航栏(即导航窗格),需通过标题样式标记文档结构+修改文档视图设置两步完成。以下是详细且经过验证的解决方案,基于pytho...

田渊栋等原班人马作:AI生成长篇故事,数千字长文也能连贯、有趣

机器之心报道编辑:小舟、陈萍以后,写故事这脑力活可以交给AI了。前段时间,模仿人类写作过程的语言模型Re^3发布,该模型不需要微调大模型,而是通过设计prompt来生成一致性强的故事。现在...

VBA常用代码_1、文本格式整理

本人财务岗位,非专业编程人员,请勿以专业看待哈,能用无BUG即可!均是我在工作中常用的补充功能,且具有通用性的功能。基于实用性而编写。不见理论,只需要你会复制粘贴就行。看完第一篇文章,结合之后更新的内...

行业首选的文档管理工具Aspose.Words新版本v16.3.0发布

Aspose.Words是一款先进的文档处理控件,在不使用MicrosoftWords的情况下,它可以使用户在各个应用程序中执行各种文档处理任务,其中包括文档的生成、修改、渲染、打印,文档格式转换和...

作为前端工程师必须懂得的33个CSS核心概念

你真的懂CSS吗?层叠样式表(CSS)是网页设计的支柱,能将单调的HTML转变为视觉惊艳的交互界面。要精通CSS,必须理解从基础选择器到动画、响应式设计等高级技巧在内的核心概念。无论你是初学者还是资深...

全力做好节假日期间服务保障工作

为保障五一期间ETC运营工作正常有序开展,甘肃省高速公路ETC管理服务中心全力以赴、恪尽职守,使各项工作有备无患。一是要求中心全体职工牢固树立安全发展观念,时刻紧绷“安全弦”,夯实安全生产基础,落实安...

Manila's hyping up of illegal 'arbitral award' nothing but a damp squib

Manila'shypingupofillegal'arbitralaward'nothingbutadampsquib:ChinaDailyeditorial-Opi...

QLabel 文字两端对齐解决方案

在Qt开发中,实现QLabel文字两端对齐是一个常见需求。本文将介绍多种在Qt中实现QLabel文字两端对齐的方法及其原理。Qt本身具备文字两端对齐的支持,但需要同时使用Qt::AlignJ...

tkinter中的一些自定义控件,你知道几个呢?

用tkinter图形库编写过界面的朋友都知道,tkinter中拥有的图形控件很少,ttk中虽然新增了一些,但是这也不足以满足我们的使用,因为我们在编写图形界面的时候会用到各种各样的控件,有些是tkin...

一个人的婚礼:她送给自己的新婚礼物是遗体捐献书

style="text-indent:2em;">1月20日,在重庆武隆区医院的病房里,爱心人士为21岁的杨春燕在医院举办了一场没有新郎的婚礼,圆了春燕穿婚纱、走红毯的心愿,仪式后春燕签署了遗体...

毕业论文小技巧:word排版之章节自动化编号

设置大纲多级列表目的是方便增删章节时实现章节标号的自动编号,并且实现论文图表公式编号按照章节顺序自动编号。准备工作:假设前面已经定义好章节标题样式分别为标题一论文章标题、论文节标题、论文小节标题、论文...

伊朗呼吁土耳其立即终止对叙军事行动

style="text-indent:2em;">新华社德黑兰1月21日电(记者马骁穆东)伊朗外交部21日发表声明说,希望土耳其立即终止在叙利亚阿夫林发起的军事行动,避免叙北部危机进一步恶化。...