Compose筆記(三十五)--ModalBottomSheetLayout

? ? ? ? ? 這一節主要了解一下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…