A:
請問「ExposedDropdownMenuBox 的內部實作」,是實作在哪一個檔案?謝謝
Q:
好的,這是一個很好的問題!在我上次為了簡化篇幅而省略了部分重複的程式碼,我現在為您補上完整的實作細節。
這個 ExposedDropdownMenuBox 的內部實作模式,我們主要是在 AddTransactionScreen.kt 這個檔案中完整使用的。在該檔案中,「帳戶選擇」、「分類選擇」和「專案選擇」都採用了完全相同的結構。
我將以「帳戶選擇」的下拉選單為例,為您詳細列出其完整的內部實作程式碼。
ExposedDropdownMenuBox 內部實作詳解
檔案路徑: app/src/main/java/com/yourcompany/cashflow/ui/screens/AddTransactionScreen.kt
在 AddTransactionScreen.kt 的 LazyColumn 中,帳戶選擇的 item 程式碼區塊應如下所示:
<details>
<summary><strong>點此展開「帳戶選擇」下拉選單的完整程式碼</strong></summary>
// ... 位於 AddTransactionScreen.kt 的 LazyColumn 內部
item {
// 1. ExposedDropdownMenuBox 作為最外層的容器
// - expanded: 控制選單是否展開,由我們自己定義的 showAccountMenu 狀態變數管理
// - onExpandedChange: 當使用者點擊輸入框或選單外部時,觸發此回呼來改變 showAccountMenu 的狀態
ExposedDropdownMenuBox(
expanded = showAccountMenu,
onExpandedChange = { showAccountMenu = !showAccountMenu }
) {
// 2. OutlinedTextField 作為顯示區域與觸發點
// - value: 顯示當前選擇的帳戶名稱,如果尚未選擇,則顯示提示文字
// - onValueChange: 保持為空,因為我們不允許使用者手動輸入
// - readOnly = true: 確保輸入框是唯讀的
// - trailingIcon: 在尾部顯示一個會根據展開狀態變換方向的箭頭圖示
// - modifier.menuAnchor(): 這是關鍵!它告訴 Box 這個輸入框是選單彈出的「錨點」
OutlinedTextField(
modifier = Modifier
.menuAnchor()
.fillMaxWidth(),
readOnly = true,
value = selectedAccount?.name ?: "選擇帳戶",
onValueChange = {},
label = { Text("帳戶") },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = showAccountMenu) }
)
// 3. ExposedDropdownMenu 是實際的下拉選單本體
// - expanded: 同樣由 showAccountMenu 控制其顯示與隱藏
// - onDismissRequest: 當使用者點擊選單外部時,觸發此回呼來關閉選單
ExposedDropdownMenu(
expanded = showAccountMenu,
onDismissRequest = { showAccountMenu = false }
) {
// 4. 遍歷從 ViewModel 取得的帳戶列表,為每一個帳戶建立一個 DropdownMenuItem
accounts.forEach { account ->
DropdownMenuItem(
text = { Text(account.name) },
onClick = {
// 當使用者點擊某個選項時:
selectedAccount = account // 1. 更新選擇的帳戶狀態
showAccountMenu = false // 2. 關閉下拉選單
}
)
}
}
}
}
</details>
總結
「分類選擇」和「專案選擇」的下拉選單,其結構與上述的「帳戶選擇」完全相同,您只需要替換以下幾個部分即可:
狀態變數: 將
showAccountMenu和selectedAccount換成對應的showCategoryMenu/selectedCategory或showProjectMenu/selectedProject。數據來源: 將
accounts.forEach換成categories.forEach或projects.forEach。顯示文字: 將
selectedAccount?.name換成selectedCategory?.name或selectedProject?.name。
這個模式是 Material 3 中實現下拉式選單最標準、最推薦的方式。