鸿蒙应用开发实战【15】— LinearGradient 线性渐变在 ArkUI 中的应用
鸿蒙应用开发实战【15】— LinearGradient 线性渐变在 ArkUI 中的应用
前言
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
渐变色是现代移动应用 UI 中最常见的视觉元素之一。在号码助手中,FAB 悬浮按钮、添加应用按钮、AvatarBadge 头像徽标都使用了线性渐变。ArkUI 的linearGradient属性与 CSS 的linear-gradient功能高度相似,但有一些细节差异需要了解。
ArkUI 与 CSS 的关键差异:ArkUI 的
angle参数方向体系与 CSS 不同。CSS 的0deg是从下到上,ArkUI 的0也是从下到上,两者一致!但多色渐变的颜色停止点位置定义略有不同。
本篇全面讲解 ArkUI 中 linearGradient 的用法和最佳实践。
一、渐变预览图
图1:linearGradient 四种基本方向 + 角度罗盘 + AvatarBadge/FAB/StatCard 三大应用场景
二、linearGradient 基本语法
2.1 参数结构
.linearGradient({angle:number|Direction,// 渐变方向(角度或枚举)direction?:GradientDirection,// 方向枚举(与 angle 二选一)colors:Array<[ColorType,number]>,// 色值数组:[颜色, 位置(0-1)]repeating?:boolean// 是否重复(默认 false)})2.2 angle 角度说明
| angle 值 | 渐变方向 | 对应 CSS |
|---|---|---|
| 0 | 从下到上(↑) | to top |
| 45 | 从右下到左上(↖) | to top left |
| 90 | 从右到左(←) | to left |
| 135 | 从右上到左下(↙) | to bottom left |
| 180 | 从上到下(↓) | to bottom |
| 225 | 从左上到右下(↘) | to bottom right |
| 270 | 从左到右(→) | to right |
| 315 | 从左下到右上(↗) | to top right |
ArkUI 与 CSS 角度体系不同:ArkUI 的 0° 是从下到上,CSS 的 0deg 也是从下到上,两者一致!但 ArkUI 使用
angle: 135对应的视觉方向与 CSSlinear-gradient(135deg, ...)方向一致。
三、号码助手中的渐变应用
3.1 FAB 添加应用按钮(蓝紫渐变)
// 首页 FAB 悬浮按钮Row({space:4}){Text('+').fontColor('#FFFFFF').fontWeight(800)Text('添加应用').fontColor('#FFFFFF')}.padding({left:20,right:20,top:13,bottom:13}).borderRadius(24).linearGradient({angle:135,// 左上→右下斜向渐变colors:[[AppColors.PRIMARY,0],// 起点:蓝色 #4F7CFF[AppColors.PRIMARY_2,1]// 终点:紫色 #7C5CFF]}).shadow({radius:22,color:'#524F7CFF',offsetY:10})// 彩色阴影3.2 空状态添加按钮(同款渐变)
// 首页空状态的添加应用按钮Row({space:4}){Text('+').fontSize(14).fontColor('#FFFFFF').fontWeight(AppFonts.WEIGHT_SEMIBOLD)Text('添加应用').fontSize(13).fontColor('#FFFFFF')}.layoutWeight(1).height(46).justifyContent(FlexAlign.Center).borderRadius(24).linearGradient({angle:135,colors:[[AppColors.PRIMARY,0],[AppColors.PRIMARY_2,1]]}).shadow({radius:22,color:'#524F7CFF',offsetY:10})3.3 AvatarBadge 头像渐变
// AvatarBadge.ets 中的渐变背景.linearGradient({angle:135,colors:[[this.colorStart,0],// 起点颜色(可与终点相同=纯色)[this.colorEnd,1]// 终点颜色]})四、多色渐变
4.1 三色渐变示例
// 三色彩虹渐变.linearGradient({angle:90,// 从右到左colors:[['#FF2E4D',0],// 起点:红['#FF7A1E',0.5],// 中点(50%处):橙['#4F7CFF',1]// 终点:蓝]})4.2 带不透明度的渐变
// 渐变从实色到透明(常用于渐隐效果).linearGradient({angle:180,// 从上到下colors:[['#FFFFFFFF',0],// 起点:完全不透明白色['#00FFFFFF',1]// 终点:完全透明(渐隐)]})4.3 号码助手卡片渐变扩展
// AppColors.cardGradient() 方法staticcardGradient(colorKey:string):[string,string]{switch(colorKey){case'blue':return[AppColors.PRIMARY,AppColors.PRIMARY_2]// 蓝→紫case'green':return['#3CC463','#6BE28E']// 深绿→浅绿case'pink':return['#FF2E4D','#FF7A90']// 深红→浅红case'orange':return['#FF7A1E','#FFB067']// 深橙→浅橙case'purple':return['#7B61FF','#9B85FF']// 深紫→浅紫default:return[AppColors.PRIMARY,AppColors.PRIMARY_2]}}// 使用const[start,end]=AppColors.cardGradient(card.color)AvatarBadge({colorStart:start,colorEnd:end})五、其他渐变类型
5.1 sweepGradient(扫描/角度渐变)
// 扫描渐变:以中心点为圆心,按角度分布颜色.sweepGradient({center:[0.5,0.5],// 中心点(相对坐标,0.5=50%处)start:0,// 起始角度(度)end:360,// 结束角度(度)colors:[['#4F7CFF',0],['#7C5CFF',0.5],['#4F7CFF',1]]})5.2 radialGradient(径向/放射渐变)
// 径向渐变:从中心向外辐射.radialGradient({center:[0.5,0.5],// 圆心位置radius:0.8,// 半径(相对单位)colors:[['#FFFFFF',0],// 中心:白色['#4F7CFF',1]// 边缘:蓝色]})六、渐变与 backgroundColor 的优先级
6.1 覆盖关系
// 同时设置 backgroundColor 和 linearGradient 时,linearGradient 优先Row().backgroundColor('#FF0000')// 红色(被覆盖).linearGradient({// 渐变(生效)angle:135,colors:[['#4F7CFF',0],['#7C5CFF',1]]})// 结果:显示蓝紫渐变,红色被完全覆盖6.2 最佳实践:不混用
// ✅ 只用 backgroundColor(纯色).backgroundColor(AppColors.CARD)// ✅ 只用 linearGradient(渐变).linearGradient({angle:135,colors:[[AppColors.PRIMARY,0],[AppColors.PRIMARY_2,1]]})// ❌ 不要同时设置两者(backgroundColor 会被忽略,造成困惑).backgroundColor('#FF0000').linearGradient({...})七、渐变按钮完整封装
7.1 GradientButton 通用组件
// 封装一个通用渐变按钮组件@Componentstruct GradientButton{@Proplabel:string='按钮'@PropcolorStart:string='#4F7CFF'@PropcolorEnd:string='#7C5CFF'@Propheight:number=46onTap?:()=>voidbuild(){Row(){Text(this.label).fontSize(14).fontWeight(600).fontColor('#FFFFFF')}.width('100%').height(this.height).justifyContent(FlexAlign.Center).borderRadius(this.height/2)// 圆角 = 高度/2 → 完全圆润.linearGradient({angle:135,colors:[[this.colorStart,0],[this.colorEnd,1]]}).shadow({radius:20,color:`${this.colorStart}52`,// 阴影颜色 = 渐变起始色 + 32% 透明度offsetY:8}).onClick(()=>{if(this.onTap){this.onTap()}})}}八、性能注意事项
8.1 渐变的 GPU 加速
// linearGradient 由 GPU 渲染,性能优于图片背景// 不需要额外优化,可以在 ForEach 中大量使用// 但如果同一渐变出现在非常多的地方,考虑封装为组件// 避免相同渐变参数重复书写8.2 动态渐变
// 渐变颜色变化时会重新计算,有少量 GPU 重绘开销// 对于静态渐变(参数不变),ArkUI 自动缓存@StategradientAngle:number=135// 动态修改 gradientAngle → 触发渐变重绘九、本篇小结
| 知识点 | 核心要点 |
|---|---|
| angle | 0°=上,90°=左,135°=斜向(号码助手全部使用 135°) |
| colors | 数组,每项 [颜色字符串, 0-1位置] |
| 多色渐变 | 可有 3 个以上色值,中间值指定位置 |
| 与 backgroundColor | 两者不混用,linearGradient 优先级更高 |
| 彩色阴影 | shadow.color 使用渐变起始色+透明度,增强立体感 |
参考资料
- 鸿蒙应用开发实战【11】— AvatarBadge 组件
- 鸿蒙应用开发实战【14】— 毛玻璃卡片颜色格式深度解析
- linearGradient API
- sweepGradient API
- radialGradient API
- shadow 属性
- 颜色类型参考
- CSS linear-gradient MDN
- HarmonyOS 视觉效果指南
- @Component 自定义组件
- @Builder 装饰器
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
- linearGradient 文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-gradient-color
- ArkUI 视觉属性:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-image-effect
