### 專案初始化與資料類別定義 - 使用空的 Jetpack Compose 專案,無需額外依賴。 - 建立 `ContactUI` 資料類別,包含 `id`、`name`、`isOptionsRevealed`。 --- ### 建立動作按鈕 Composable `ActionIcon` - 接收 `onClick`、`backgroundColor`、`icon`、`tint`、`contentDescription` 參數。 - 使用 `IconButton` 搭配 `Icon` 呈現動作圖示。 - 背景色與圖示皆可自訂,方便重複使用。 --- ### 建立 `SwipeableItemWithActions` Composable - 接收是否展開、動作區 Composables、展開與收起事件、主要內容。 - 透過 `Box` 疊加動作列與主要內容。 - 背景使用 `Row` 放置動作圖示,內容以 `Surface` 包覆。 --- ### 控制動畫與狀態 - 使用 `Animatable` 控制 offset 水平偏移。 - 使用 `rememberCoroutineScope()` 建立協程環境。 - 儲存 context menu 寬度作為滑動邊界依據。 --- ### 拖曳手勢偵測與邊界控制 - 使用 `pointerInput` 搭配 `detectHorizontalDragGestures` 偵測拖曳行為。 - 拖曳時即時更新偏移量並限制在 0 到 context menu 寬度之間。 - 拖曳結束後根據偏移比例決定展開或收合,並觸發動畫。 --- ### 使用 offset 改善效能 - 使用 `Modifier.offset` 搭配 lambda 傳入值避免不必要重組。 - 不使用 `dp` 版的 offset 以減少 recomposition。 --- ### 動畫控制與條件邏輯 - 若拖曳距離大於一半寬度,使用 `animateTo` 展開。 - 若不足一半寬度,使用 `animateTo` 收回。 - 拖曳中使用 `snapTo` 立即更新視圖,不產生動畫。 --- ### 自動響應狀態變化 - 使用 `LaunchedEffect` 監聽 `isRevealed` 與 context menu 寬度。 - 狀態變為 true 時展開,為 false 時收合,支援程式控制。 --- ### 拖曳結束後的展開與收合處理 - 拖曳結束後檢查目前偏移量是否超過 context menu 寬度的一半。 - 若大於等於一半,使用 `animateTo` 展開並呼叫 `onExpanded`。 - 否則收合並呼叫 `onCollapsed`。 --- ### 支援外部控制展開狀態 - 使用 `LaunchedEffect` 監聽 `isRevealed` 及 context menu 寬度變化。 - 當 `isRevealed` 為 true 時展開,為 false 時收合。 - 支援透過程式邏輯改變展開狀態。 --- ### 建立 Contact 畫面與假資料 - 使用 `remember` 搭配 `mutableStateListOf` 建立 100 筆假資料。 - 每筆資料包含 id、name、isOptionsRevealed(預設為 false)。 - 使用展開運算子避免建立巢狀 list。 --- ### 建立 LazyColumn 並顯示資料 - 使用 `LazyColumn` 顯示聯絡人清單。 - 每項目使用 `SwipeableItemWithActions` 包裹。 - 初期使用 `key`,後續因搭配 `mutableStateList` 不再需要。 --- ### 動作列圖示與邏輯處理 - 三個動作按鈕:刪除、Email、分享。 - 點擊刪除時從清單中移除該聯絡人並顯示 toast。 - 點擊其他動作後,自動收合選單並顯示對應 toast。 --- ### 收合狀態未正確觸發之修正 - 忘記在 `SwipeableItemWithActions` 中設定 `onExpanded` 和 `onCollapsed`。 - 補上後可正確切換 `isOptionsRevealed` 狀態並觸發動畫。 --- ### 解決刪除後滑動崩潰的問題 - 刪除項目後再次滑動導致崩潰,原因是搭配 `mutableStateListOf` 使用 `key` 無實際效果。 - 移除 `key` 即可,因為 `mutableStateList` 已具備追蹤變化能力。 --- ### 功能驗證與執行結果 - UI 可正常滑動展開與執行動作。 - 點擊非刪除動作後選單自動收合。 - 刪除項目後不會再發生錯誤,功能正常執行。 # Terminology - **Swipeable Item with Actions**:可滑動並顯示操作按鈕的列表項目。 - **Jetpack Compose**:Android 的現代聲明式 UI 框架,用於構建使用者介面。 - **LazyColumn**:Jetpack Compose 中的垂直滾動清單,僅渲染可視區塊。 - **Composable Function**:可以構建 UI 的函式,透過 @Composable 註解標示。 - **MutableState**:可觀察的狀態變數,變更時會觸發重組。 - **mutableStateListOf**:可觀察的清單結構,支援動態操作與 UI 更新。 - **remember**:用於在重組中保留狀態或值。 - **Animatable**:具有動畫能力的變數,可平滑變更其值。 - **CoroutineScope**:執行非同步作業的協程作用域。 - **graphicsLayer**:可設定元件的圖形層屬性,如偏移、旋轉、縮放等。 - **offset Modifier**:將元件內容偏移而非重組的修飾符。 - **Box**:可疊加顯示子組件的容器。 - **Row**:水平排列子組件的容器。 - **Surface**:Material 組件,提供背景、陰影與互動效果。 - **IntrinsicSize.Min**:以子組件的最小高度作為容器高度。 - **Modifier.fillMaxWidth()**:使元件寬度填滿父容器。 - **Modifier.fillMaxSize()**:使元件寬高皆填滿父容器。 - **onGloballyPositioned**:獲取元件在畫面上尺寸與位置的回呼函式。 - **onSizeChanged**:在元件尺寸改變時觸發的回呼。 - **pointerInput**:設定手勢處理邏輯的修飾符。 - **detectHorizontalDragGestures**:偵測水平方向拖曳的手勢。 - **onDragEnd**:拖曳手勢結束時的處理邏輯。 - **snapTo**:立即變更 Animatable 的值,無動畫過渡。 - **animateTo**:透過動畫變更 Animatable 的值。 - **coerceIn**:限制數值範圍以避免溢出。 - **Modifier.padding()**:設定元件的內邊距。 - **ImageVector**:向量圖標資源,用於顯示圖示。 - **IconButton**:具有點擊事件的圖示按鈕。 - **Icon**:顯示向量圖形的組件。 - **ActionIcon**:自定義可重複使用的操作圖標組件。 - **Contextual Actions**:與特定清單項目相關的操作,例如刪除或分享。 - **ContentDescription**:無障礙說明文字,用於輔助設備。 - **LaunchedEffect**:根據指定 key 執行副作用(如動畫)的函式。 - **Composable Lambda**:接受 @Composable 區塊作為參數的函式。 - **RowScope**:在 Row 中使用的作用範圍,允許加入子元件。 - **empty lambda `{}`**:作為預設值的空 Lambda。 - **State Hoisting**:將狀態從子組件提取到父組件進行管理。 - **Programmatic Reveal**:透過程式邏輯顯示操作項目,而非手勢操作。 - **spread operator (`*`)**:Kotlin 中展開陣列為多個參數的語法。 - **List.map()**:將清單中的每個元素轉換成另一個元素。 - **toast.makeText()**:在畫面上顯示短暫提示訊息的函式。 - **Toast.LENGTH_SHORT**:Toast 顯示時間的短時間常數。 - **Context**:Android 中取得資源與環境資訊的基礎物件。 - **Modifier.background()**:設定元件的背景色。 - **Drag Threshold**:決定滑動動作是否觸發顯示操作按鈕的距離。 - **State Synchronization**:內部動畫狀態與外部布林控制同步處理。 - **Modifier.then()**:鏈接多個 Modifier 的 Kotlin 擴充函式。 - **Modifier.graphicsLayer()**:透過圖形層實現動畫與效果而非重新組合。 - **List.remove()**:從清單中移除指定元素的方法。 - **Action Row**:滑動後顯示的操作圖標橫列。 - **ViewModel(推薦但未實作)**:管理 UI 資料與邏輯的生命週期感知組件。 - **itemsIndexed()**:LazyColumn 中可取得索引與項目的函式。 - **Key Lambda**:指定唯一鍵以優化 Compose 重組行為。 - **Modifier.height(IntrinsicSize.Min)**:根據最小內容高度決定容器高度。 - **State-driven UI**:UI 根據狀態變更而自動更新的設計理念。 - **Composable Composition**:Compose 的組成階段,構建 UI 階層結構。 - **Recomposition**:當狀態變更時重新渲染 UI 的過程。 - **Modifier.pointerInput() with Unit key**:防止不必要的重新註冊手勢事件。 - **GraphicsLayer TranslationX**:使用圖形層平移內容避免重組。 - **Swipe Gesture Detection**:偵測使用者水平方向滑動的手勢。 - **Offset Animation**:將項目滑動至特定位置的動畫過渡。 - **Half Width Threshold**:設定項目滑動超過一半寬度後觸發的判斷基準。 - **animateTo()**:使動畫值以過渡方式變更至指定數值的函數。 - **snapTo()**:使動畫值立即跳轉至指定數值的函數,無動畫。 - **onExpanded Callback**:當項目被滑動到展開狀態時觸發的函數。 - **onCollapsed Callback**:當項目滑動收回時觸發的函數。 - **isRevealed Boolean**:控制項目是否應顯示操作圖標的布林值。 - **LaunchedEffect Key Observation**:觀察特定變數變化並執行副作用的函式。 - **External State Control**:由外部程式碼控制項目是否展開或收回。 - **ContactUI**:表示聯絡人資料的資料類型,包含 id、名稱與選單狀態。 - **remember { mutableStateListOf() }**:建立可追蹤變化的清單狀態。 - **List.map()**:將清單轉換成另一型別或格式的常見函式。 - **Spread Operator (`*`)**:在 Kotlin 中展開陣列或清單作為參數。 - **LazyColumn.itemsIndexed()**:建立可存取索引值的列表項目。 - **Composable Item Builder**:使用索引與資料模型建立 UI 項目的邏輯。 - **Action Row**:滑動後顯示的圖標操作列。 - **IconButton Modifier.fillMaxHeight()**:讓按鈕圖標填滿操作列的高度。 - **Toast Message**:短暫提示訊息,提供使用者即時反饋。 - **context.makeText().show()**:建立並顯示 Toast 的方法。 - **Delete Contact Action**:點擊刪除按鈕後從清單移除項目的動作。 - **Send Email Action**:模擬寄信操作,觸發回饋提示。 - **Share Contact Action**:模擬分享操作,觸發回饋提示。 - **Update Contact State**:變更聯絡人資料中 `isOptionsRevealed` 值。 - **Recomposition Triggering**:因狀態改變觸發組件重組。 - **Modifier.padding(8.dp)**:為列表項目設置間距。 - **Keyless LazyColumn**:不指定鍵值時依據內容自動追蹤變化。 - **Avoid Redundant Key in MutableStateList**:避免在可變清單中使用 keys。 - **Immutable List with Keys**:使用不可變清單時需搭配 key 以提升效率。 - **StateList In-Place Modification**:直接修改特定項目以更新 UI。 - **Recomposition Efficiency**:只重組狀態變動的 UI 區塊。 - **isOptionsRevealed Update Flow**:顯示/隱藏操作列的邏輯流程。 - **LazyColumn Performance**:透過懶加載技術優化長列表顯示。 - **Icon Color Visibility**:確保圖標與背景色對比清晰。 - **Modifier.background()**:為按鈕或容器設定背景色。 - **Modifier.offset() with Lambda**:避免過多重組的偏移方式。 - **GraphicsLayer Translation**:圖層轉換以產生動畫效果。 - **PointerInput Modifier**:添加自訂手勢處理的修飾符。 - **HorizontalDragGestureDetector**:偵測水平方向拖曳動作的邏輯。 - **DragAmount Constraint**:拖曳量受限於預設最大與最小值。 - **CoroutineScope.launch**:啟動協程處理動畫或手勢事件。 - **Val NewOffset Calculation**:透過當前偏移與拖曳差計算新偏移。 - **coerceIn(0f, maxWidth)**:限制偏移值在有效範圍內。 - **ContactScreen Composable**:顯示聯絡人清單與處理滑動邏輯的畫面。 - **Text("Contact ${id}")**:顯示聯絡人項目的基本內容。 - **Modifier.fillMaxSize()**:讓元件填滿所有可用空間。 - **List.remove(contact)**:從清單中移除指定聯絡人。 - **LaunchAppEntry()**:在 MainActivity 中呼叫的起始 Composable。 - **Animation Trigger by State Change**:狀態變更驅動動畫執行。 - **Collapse on Action Click**:當按下操作按鈕後自動收回滑動項目。 - **ActionIcon Component**:封裝背景與圖標按鈕的自定義組件。 - **Modifier.then() 合併修飾符**:組合多個 Modifier 的方式。 - **滑動寬度控制(cardWidth)**:控制動畫與判斷條件的寬度參數。