这一节主要了解一下Compose中的ModalBottomSheetLayout,在Jetpack Compose开发中,ModalBottomSheetLayout是Material Design组件库中用于实现模态底部面板的核心组件,其核心作用是通过声明式API管理底部面板的显示、隐藏及交互逻辑。

API
ModalBottomSheetLayout:作为容器使用,管理底部sheet的状态和行为
sheetState:控制底部sheet的状态(展开、折叠、隐藏)
sheetShape:定义底部sheet的形状(通常使用圆角)
sheetElevation:控制底部sheet的阴影效果
sheetContent:底部sheet的内容区域
scrimColor:背景遮罩层的颜色

场景:
1 表单输入/选择,用户需要从多个选项中选择或填写简单表单(如添加备注)。
2 详情展示,点击列表项后,底部弹窗展示详细信息
3 操作菜单,提供一组操作按钮(如分享、删除、编辑)。

栗子:

app下gradle添加依赖

  implementation "androidx.compose.material:material:1.4.3"
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dpimport kotlinx.coroutines.launch
import androidx.compose.material.ModalBottomSheetLayout@Composable
fun FormModalBottomSheet() {val sheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)val scope = rememberCoroutineScope()var name by remember { mutableStateOf("") }var email by remember { mutableStateOf("") }var submitted by remember { mutableStateOf(false) }ModalBottomSheetLayout(sheetState = sheetState,sheetContent = {Column(modifier = Modifier.fillMaxWidth().padding(16.dp).padding(bottom = 40.dp)) {Text(text = "请填写信息",style = MaterialTheme.typography.h5,modifier = Modifier.padding(bottom = 16.dp))OutlinedTextField(value = name,onValueChange = { name = it },label = { Text("姓名") },modifier = Modifier.fillMaxWidth().padding(bottom = 16.dp))OutlinedTextField(value = email,onValueChange = { email = it },label = { Text("邮箱") },modifier = Modifier.fillMaxWidth().padding(bottom = 16.dp))Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.End) {Button(onClick = { scope.launch { sheetState.hide() } },modifier = Modifier.padding(end = 8.dp)) {Text("取消")}Button(onClick = {submitted = truescope.launch { sheetState.hide() }}) {Text("提交")}}}}) {Column(modifier = Modifier.fillMaxSize(),verticalArrangement = Arrangement.Center,horizontalAlignment = Alignment.CenterHorizontally) {Button(onClick = { scope.launch { sheetState.show() } }) {Text("打开表单")}if (submitted && name.isNotEmpty() && email.isNotEmpty()) {Spacer(modifier = Modifier.height(16.dp))Card(elevation = 4.dp,modifier = Modifier.padding(16.dp)) {Column(modifier = Modifier.padding(16.dp)) {Text("提交成功", style = MaterialTheme.typography.h6)Spacer(modifier = Modifier.height(8.dp))Text("姓名: $name")Text("邮箱: $email")}}}}}
}
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.launch@OptIn(ExperimentalMaterialApi::class)
@Composable
fun CategoryModalBottomSheet() {val sheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)val scope = rememberCoroutineScope()val categories = listOf("水果", "蔬菜", "零食", "饮料")// 商品数据val products = mapOf("水果" to listOf("苹果", "香蕉", "橙子", "草莓", "葡萄", "西瓜", "芒果"),"蔬菜" to listOf("胡萝卜", "西红柿", "黄瓜", "土豆", "西兰花", "洋葱", "生菜"),"零食" to listOf("薯片", "巧克力", "饼干", "坚果", "糖果", "牛肉干", "果冻"),"饮料" to listOf("可乐", "雪碧", "果汁", "茶饮料", "咖啡", "牛奶", "矿泉水"))var selectedCategory by remember { mutableStateOf(categories.first()) }var selectedProduct by remember { mutableStateOf<String?>(null) }ModalBottomSheetLayout(sheetState = sheetState,sheetShape = MaterialTheme.shapes.large,sheetContent = {Column(modifier = Modifier.fillMaxWidth().padding(bottom = 30.dp)) {Box(modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp).wrapContentSize(Alignment.Center)) {Box(modifier = Modifier.width(32.dp).height(4.dp).clip(MaterialTheme.shapes.small).background(Color.Gray.copy(alpha = 0.3f)))}ScrollableTabRow(selectedTabIndex = categories.indexOf(selectedCategory),backgroundColor = Color.Transparent,edgePadding = 0.dp) {categories.forEachIndexed { index, category ->Tab(selected = selectedCategory == category,onClick = { selectedCategory = category },text = {Text(text = category,fontWeight = if (selectedCategory == category) FontWeight.Bold else FontWeight.Normal)},modifier = Modifier.padding(horizontal = 8.dp))}}// 商品列表LazyColumn(modifier = Modifier.fillMaxWidth().height(300.dp).padding(horizontal = 16.dp, vertical = 8.dp)) {items(products[selectedCategory] ?: emptyList()) { product ->ProductItem(product = product,isSelected = selectedProduct == product,onClick = {selectedProduct = productscope.launch { sheetState.hide() }})}}}}){Scaffold(topBar = {TopAppBar(title = { Text("商品选择器") },backgroundColor = MaterialTheme.colors.primary)},content = { padding ->Box(modifier = Modifier.fillMaxSize().padding(padding),contentAlignment = Alignment.Center) {Column(horizontalAlignment = Alignment.CenterHorizontally) {Button(onClick = { scope.launch { sheetState.show() } },modifier = Modifier.padding(16.dp)) {Text("选择商品")}if (selectedProduct != null) {Card(modifier = Modifier.padding(16.dp).fillMaxWidth().wrapContentHeight(),elevation = 4.dp) {Column(modifier = Modifier.padding(16.dp),horizontalAlignment = Alignment.CenterHorizontally) {Text(text = "已选择商品",fontSize = 16.sp,fontWeight = FontWeight.Bold,modifier = Modifier.padding(bottom = 8.dp))Text(text = selectedProduct!!,fontSize = 24.sp,fontWeight = FontWeight.Bold,color = MaterialTheme.colors.primary)Spacer(modifier = Modifier.height(16.dp))Button(onClick = { selectedProduct = null },colors = ButtonDefaults.buttonColors(backgroundColor = Color.LightGray)) {Text("清除选择")}}}}}}})}
}@Composablefun ProductItem(product: String,isSelected: Boolean,onClick: () -> Unit) {Box(modifier = Modifier.fillMaxWidth().height(56.dp).clickable(onClick = onClick).padding(vertical = 8.dp),contentAlignment = Alignment.CenterStart) {Row(verticalAlignment = Alignment.CenterVertically,modifier = Modifier.fillMaxSize()) {Text(text = product,fontSize = 16.sp,modifier = Modifier.weight(1f))if (isSelected) {Icon(painter = painterResource(id = android.R.drawable.checkbox_on_background),contentDescription = "已选择",tint = MaterialTheme.colors.primary)}}Divider(color = Color.LightGray.copy(alpha = 0.5f),modifier = Modifier.fillMaxWidth().height(0.5.dp).align(Alignment.BottomCenter))}}

注意:
1 状态管理,使用rememberModalBottomSheetState()控制弹窗的展开/折叠状态。
2 避免弹窗内容过多,必要时分页或滚动。
3 性能优化,复杂内容使用LazyColumn或LazyRow 避免卡顿。避免在弹窗内加载大量数据,可预加载或分页。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/89606.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/89606.shtml
英文地址,请注明出处:http://en.pswp.cn/web/89606.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AWS Partner: Accreditation (Technical)

AWS Partner: Accreditation &#xff08;Technical&#xff09;AWS 核心技术简介云计算的优势AWS 全球基础设施核心技术&#xff1a;计算 Amazon Elastic Compute Cloud (Amazon EC2)存储数据库联网安全性从服务到解决方案解决方案设计简介迁移策略架构最佳实践AWS Well-Archi…

【52】MFC入门到精通——(CComboBox)下拉框选项顺序与初始化不一致,默认显示项也不一致

文章目录1 问题描述2 问题分析与解决上一讲&#xff0c;我们实现了MFC串口助手初级版。 MFC入门到精通——MFC串口助手(一)—初级版&#xff08;串口设置、初始化、打开/关闭、状态显示&#xff09;,附源码1 问题描述 程序运行后串口默认参数&#xff0c;与我们预期不完全一致…

Astro:前端性能革命!从原生 HTML 到 Astro + React 的升级指南

为什么程序员必须关注 Astro在网站性能和 SEO 日益关键的今天&#xff0c;静态站点生成&#xff08;SSG&#xff09;再次成为焦点。Astro 作为一款专为内容驱动网站设计的现代前端框架&#xff0c;正引领一场轻盈革命。它强调服务器优先渲染&#xff0c;将页面预先转为纯 HTML&…

格式转换Total Excel Converter:20 种格式XLS XLSX 批量转 PDFWord

各位办公小能手们&#xff01;今天给大家介绍一款超厉害的软件&#xff0c;叫Total Excel Converter&#xff0c;软件下载地址安装包 它可是专业的Excel文件格式转换工具。你知道吗&#xff0c;它能把Excel工作簿&#xff0c;像XLS、XLSX、XLSM这些格式&#xff0c;批量转换成…

Thread,ThreadLocal,ThreadLocalMap 三者的关系, 以及在实际开发中的应用【AI记录用】

在 Java 多线程编程中&#xff0c;Thread、ThreadLocal 和 ThreadLocalMap 是三个紧密相关的类&#xff0c;它们共同构成了 Java 中**线程本地变量&#xff08;Thread-Local Storage&#xff09;**机制的基础。下面我将从 三者的关系、实现原理 以及 实际开发中的应用 三个方面…

[故障诊断方向]SNNs:针对小样本轴承故障诊断的孪生神经网络模型

目录 1. ​引言与背景总结​ 2. ​方法框架总结​ 3. ​训练策略总结​ 4. ​实验验证总结​ 核心代码实现&#xff08;PyTorch框架&#xff09; ​1. SNN特征提取器&#xff08;多尺度卷积模块&#xff09; ​结论与未来工作总结​ 1. ​引言与背景总结​ ​问题陈述​…

Java中缓存的使用浅讲

Java中缓存的使用浅讲在Java中&#xff0c;缓存系统的使用对于提升应用性能至关重要。缓存的作用主要是减少访问慢速存储&#xff08;如数据库或文件系统&#xff09;的频率&#xff0c;从而提高应用的响应速度。以下是对Java中缓存系统的全面讲解&#xff0c;包括缓存的类型、…

洛谷 P10264 [GESP202403 八级] 接竹竿 普及+/提高

题目描述 小杨同学想用卡牌玩一种叫做“接竹竿”的游戏。 游戏规则是&#xff1a;每张牌上有一个点数 vvv&#xff0c;将给定的牌依次放入一列牌的末端。若放入之前这列牌中已有与这张牌点数相 同的牌&#xff0c;则小杨同学会将这张牌和点数相同的牌之间的所有牌全部取出队列&…

windows docker-02-docker 最常用的命令汇总

一、镜像管理命令说明常用参数示例docker pull <镜像名>:<标签>拉取镜像docker pull nginx:latestdocker images查看本地镜像docker images -a&#xff08;含中间层镜像&#xff09;docker rmi <镜像ID>删除镜像docker rmi -f $(docker images -q)&#xff0…

前端react项目目录详解

1. 项目根目录文件​​文件/目录作用​​package.json​​定义项目依赖、脚本命令&#xff08;如 start/build&#xff09;、版本信息等​​.env​​基础环境变量配置&#xff08;所有环境共享&#xff09;​​.env.development​​开发环境专用变量&#xff08;如本地API地址&…

前端-CSS (样式引入、选择器)

文章目录大纲前端三大件常用样式颜色px:像素1.CSS三种引入方式1.1 行内样式1.2 页内样式1.3 引入外部样式表文件&#xff08;常见&#xff09;基础选择器1. 标记选择器2. id选择器3. 类选择器 最常用4 * 选择器 使用频率较低复合选择器伪类选择器1.超链接伪类&#xff1a;2.子元…

7月19日 台风“韦帕“强势逼近:一场与时间赛跑的防御战

中央气象台7月19日10时继续发布台风黄色预警,今年第6号台风"韦帕"正以每小时20-25公里的速度向西偏北方向移动,强度逐渐加强。这个来自海洋的"不速之客"中心附近最大风力已达10级(25米/秒),预计将于20日下午至夜间在广东深圳到海南文昌一带沿海登陆,…

学习 Python 爬虫需要哪些基础知识?

学习 Python 爬虫需要掌握一些基础技术和概念。 1. Python 基础语法 这是最根本的前提&#xff0c;需要熟悉&#xff1a; - 变量、数据类型&#xff08;字符串、列表、字典等&#xff09; - 条件判断、循环语句 - 函数、类与对象 - 模块和包的使用&#xff08;如 import 语…

IELTS 阅读C15-Test 2-Passage 2

继续雅思上分实验。这次正确率是10/13&#xff0c;还是挺让我吃惊的&#xff0c;因为我又没有完全读懂&#xff01; 题型1-填空题这道题目很简单&#xff0c;同样地去原文段落里找就好&#xff0c;最后一个空填错了是因为我不知道mitigate就是decrease同义词。 题型2-人物匹配题…

7.18 Java基础 |

以下内容&#xff0c;参考Java 教程 | 菜鸟教程&#xff0c;下边是我边看边记的内容&#xff0c;以便后续复习使用。 多态&#xff1a; 继承&#xff0c;接口就是多态的具体体现方式。生物学上&#xff0c;生物体或物质可以具有许多不同的形式或者阶段。 多态分为运行时多态&…

网络安全知识学习总结 Section 11

一、实验知识总结&#xff08;模拟&#xff09;等价路由配置实验并抓包分析按流分析实验拓扑图&#xff1a;AR1配置&#xff1a;<Huawei>sys [Huawei]int g0/0/0 [Huawei-GigabitEthernet0/0/0]ip address 192.168.1.1 30 [Huawei-GigabitEthernet0/0/0]int g0/0/1 [Huaw…

VBA 运用LISTBOX插件,选择多个选项,并将选中的选项回车录入当前选中的单元格

维护好数据&#xff0c;并新增一个activeX列表框插件Private Sub Worksheet_SelectionChange(ByVal Target As Range)If Target.Count > 1 Then Exit SubIf Target.Row > 2 And Target.Row < 10 And Target.Column 2 Then 选择操作范围With ListBox1.MultiSelect 1 …

ASP .NET Core 8实现实时Web功能

ASP.NET Core SignalR 是一个开放源代码库&#xff0c;可用于简化向应用添加实时 Web 功能。 实时 Web 功能使服务器端代码能够将内容推送到客户端。以下是 ASP.NET Core SignalR 的一些主要功能&#xff1a;自动处理连接管理同时向所有连接的客户端发送消息。 例如聊天室向特定…

最新版谷歌浏览器 内网安装 pdf无法预览

最新版谷歌浏览器 内网安装 pdf无法预览 谷歌下载地址 谷歌下载地址 不同的浏览器版本&#xff0c;兼容的js标准不一样 js标准也在不断升级&#xff0c;增加新的方法。

NX二次开发常用函数坐标转化UF_MTX4_csys_to_csys和UF_MTX4_vec3_multipl

一、UF_MTX4_csys_to_csys 1.1 函数名称 UF_MTX4_csys_to_csys1.2 函数中各参数解释&#xff1a;函数参数解释&#xff1a; 第1个参数为输入&#xff1a; 输入const double 双精度类型的参数&#xff0c;参数的变量格式为from_origin [ 3 ]&#xff0c;坐标系&#xff…