当前位置: 首页 > news >正文

第六章:UI组件与Material3主题

第六章:UI 组件与 Material3 主题

Material3 是 Android 最新设计语言,Compose 原生支持,主题配置更简单。


6.1 主题配置

// Theme.kt@ComposablefunMyFirstComposeTheme(darkTheme:Boolean=isSystemInDarkTheme(),dynamicColor:Boolean=true,content:@Composable()->Unit,){valcolorScheme=when{dynamicColor&&Build.VERSION.SDK_INT>=Build.VERSION_CODES.S->{valcontext=LocalContext.currentif(darkTheme)dynamicDarkColorScheme(context)elsedynamicLightColorScheme(context)}darkTheme->DarkColorSchemeelse->LightColorScheme}MaterialTheme(colorScheme=colorScheme,typography=Typography,content=content,)}

主题特点:

  • dynamicColor— Android 12+ 支持从壁纸提取颜色
  • darkTheme— 自动跟随系统深色模式
  • colorScheme— Material3 颜色体系(primary/secondary/tertiary)

6.2 颜色定义

// Color.ktvalPurple80=Color(0xFFD0BCFF)valPurpleGrey80=Color(0xFFCCC2DC)valPink80=Color(0xFFEFB8C8)valPurple40=Color(0xFF6650a4)valPurpleGrey40=Color(0xFF625b71)valPink40=Color(0xFF7D5260)
颜色角色浅色模式深色模式
primaryPurple40Purple80
secondaryPurpleGrey40PurpleGrey80
tertiaryPink40Pink80

6.3 通用组件:ArticleItem

列表卡片组件:

@ComposablefunArticleItem(title:String,description:String?,thumbnail:String?,onClick:()->Unit,){Card(modifier=Modifier.fillMaxWidth().padding(12.dp).clickable(onClick=onClick),){Column{ArticleImage(imageUrl=thumbnail.orEmpty(),contentDescription=title,modifier=Modifier.fillMaxWidth().height(180.dp),)Text(text=title,fontWeight=FontWeight.Bold)Text(text=description?:"暂无描述")}}}

Card 特点:

  • 带圆角和阴影的容器
  • modifier 配置点击事件
  • 内部 Column 竖向排列子组件

6.4 图片组件:ArticleImage

预览模式下显示占位图,运行时加载网络图片:

@ComposablefunArticleImage(imageUrl:String,modifier:Modifier=Modifier,contentDescription:String?=null,){if(LocalInspectionMode.current){// Preview 模式:显示占位图,不发网络请求Box(modifier=modifier.background(MaterialTheme.colorScheme.surfaceVariant),contentAlignment=Alignment.Center,){Icon(Icons.Default.Image,contentDescription=contentDescription)}}else{// 运行时:使用 Coil 加载网络图片AsyncImage(model=imageUrl,contentDescription=contentDescription,modifier=modifier,contentScale=ContentScale.Crop,)}}

LocalInspectionMode:

  • Composable 在 Android Studio Preview 时为 true
  • 用于区分预览环境与真实运行环境

6.5 轮播图组件:BannerView

使用 HorizontalPager 实现自动轮播:

@ComposablefunBannerView(images:List<String>){if(images.isEmpty())returnvalpagerState=rememberPagerState(pageCount={images.size})LaunchedEffect(Unit){while(true){delay(3000)valnextPage=(pagerState.currentPage+1)%images.size pagerState.animateScrollToPage(nextPage)}}Box{HorizontalPager(state=pagerState,modifier=Modifier.height(200.dp)){page->AsyncImage(model=images[page],contentDescription=null)}// 底部指示器Row(modifier=Modifier.align(Alignment.BottomCenter)){repeat(images.size){index->Box(modifier=Modifier.size(8.dp).clip(CircleShape).background(if(pagerState.currentPage==index)Color.WhiteelseColor.Gray))}}}}

关键点:

  • rememberPagerState保存分页状态
  • LaunchedEffect启动协程控制自动轮播
  • 页面指示器根据当前页切换颜色

6.6 头像组件:ProfileAvatar

@ComposablefunProfileAvatar(avatarUrl:String,modifier:Modifier=Modifier){if(LocalInspectionMode.current){Box(modifier=modifier.clip(CircleShape).background(primary.copy(alpha=0.15f)),contentAlignment=Alignment.Center,){Icon(Icons.Default.Person,modifier=Modifier.size(48.dp))}}else{AsyncImage(model=avatarUrl,contentDescription="用户头像",modifier=modifier.clip(CircleShape),contentScale=ContentScale.Crop,)}}

6.7 主题使用示例

@ComposablefunDetailArticleBody(article:ArticleBean){Column(modifier=Modifier.padding(16.dp)){Text(text=article.title,style=MaterialTheme.typography.headlineSmall,// 使用主题字体fontWeight=FontWeight.Bold,)Text(text=${"%.2f".format(article.price)}",color=MaterialTheme.colorScheme.primary,// 使用主题颜色fontSize=22.sp,)Card(colors=CardDefaults.cardColors(containerColor=MaterialTheme.colorScheme.surfaceContainerHigh,),){/* ... */}}}

6.8 总结

  • Material3 主题支持动态颜色(Android 12+)
  • LocalInspectionMode 区分预览/运行模式
  • Coil 异步加载网络图片
  • HorizontalPager 实现轮播
  • Card 提供圆角阴影容器
  • 颜色/字体均通过 MaterialTheme 主题统一管理

上一章:第五章:数据层 — 网络请求与 Repository 下一章:第七章:状态管理实战与架构总结

http://www.cnnetsun.cn/news/2445133.html

相关文章:

  • 为什么 SAP S/4HANA 的前端更常用 SAPUI5,而不是 React、Vue 或 Angular
  • 如何用SD-PPP AI插件彻底改变你的Photoshop设计流程:创意工作者的终极指南
  • 跨平台网盘文件下载解决方案:LinkSwift 直链下载助手完全指南
  • 企业无线网络进阶:FreeRadius服务器配置与TLS证书实战
  • 健身房私教管理系统 01:用户体系与多角色注册闭环
  • CAXA 等距线(偏移)
  • OpenJDK vs OracleJDK:从许可、性能到生态,企业级项目选型实战指南
  • SeaCMS V10.1后台IP安全设置功能竟成RCE入口?聊聊CNVD-2020-22721的漏洞原理与修复
  • AgentBox:基于容器化与Cascade协议的多AI智能体协作平台架构与实践
  • 别再死记命令了!图解GRE over IPSec工作原理与配置逻辑(附抓包分析)
  • 股票数据API接口:(沪深A股)如何获取股票指历史分时BOLL数据
  • Redis分布式锁进阶第九十七篇
  • NotebookLM如何秒级解析PDF文献并生成标准参考文献?——实测12种期刊格式一键适配
  • 快速上手SketchUp STL插件:5分钟实现3D模型到打印的无缝转换
  • 互联网大厂 Java 求职面试:微服务架构与 Spring Cloud
  • 【ElevenLabs企业级克隆部署白皮书】:单模型支持12种语境情绪、延迟<480ms、通过GDPR+CCPA双认证
  • 抖音批量下载器:构建高效内容采集自动化工作流
  • 手把手教你用STM32F103和Modbus RTU做个简易PLC:从硬件接线到功能码解析
  • ‌程序员安慰师:治疗被AI羞辱的开发者‌
  • STM32新手避坑指南:用FSMC驱动2.8寸TFTLCD(ILI9341)的完整配置流程
  • ‌数字孟婆汤:选择性遗忘算法的记忆清除测试‌
  • 闲鱼淘MacBook Pro避坑指南:从个人卖家识别到收货验机全流程(附18款13寸配置推荐)
  • HNSW算法核心机制解析与Faiss实战调优
  • SAP顾问实战:当F1和SE16N都失效时,我是如何用观察点调试找到那个“幽灵”字段的
  • 别再让Latch坑了你的FPGA时序!Verilog新手避坑指南(附代码示例)
  • 信创浪潮下国产数据库怎么选:一张表帮你理清思路
  • 【NotebookLM运动科学实战指南】:3大未公开技巧让科研效率提升300%,运动科学家已悄悄启用
  • 用CanMV-K230开发板做个智能门锁原型:从硬件选型到AI模型部署的完整流程
  • 企业微信欢迎语功能教程:新客户添加后如何自动触达?
  • NotebookLM博物馆学工作流搭建全教程:1个账号、5类元数据、9种Prompt模板,即刻激活沉睡馆藏