---
# System prepended metadata

title: '[Video Note] [Android] [Material3] Philipp Lackner - Bottom Navigation Bar With Badges - UX With Material3'
tags: [Material 3, Android, Video Note]

---

### Material 2 與 Material 3 差異

- Material 2 稱為 Bottom Navigation View，Material 3 改為 Navigation Bar  
- 功能與使用方式一致，皆用於多畫面導覽  
- 僅用於畫面切換，不處理當前畫面的操作功能  

---

### 使用時機與建議

- 僅適用於 3 至 5 個畫面（destination）  
- 畫面少於 3 個不建議使用，視覺不佳  
- 可結合 badge 顯示提示訊息或更新  
- 大螢幕裝置可改用 Navigation Rail  

---

### 實作結構（Jetpack Compose）

- 使用 Scaffold 為整體容器  
- bottomBar 區塊放入 NavigationBar  
- 每個項目使用 NavigationBarItem  
- 無需客製設定，沿用預設樣式即可  

---

### 導航項目資料模型

- 使用資料類型 BottomNavigationItem  
- 含 title、selectedIcon、unselectedIcon、hasNews、badgeCount  
- badgeCount 為 null 則不顯示數字，只顯示紅點  

---

### 導航項目範例

- Home：顯示填滿圖示，無 badge  
- Chat：顯示未讀數字 badge（如 12）  
- Settings：顯示紅點提示，有更新通知  

---

### Material 3 圖示使用建議

- 當前畫面 icon 使用 Filled 樣式  
- 非當前畫面 icon 使用 Outlined 樣式  
- 有助於使用者辨識目前所在畫面  

---

### 將 BottomNavigationItem 清單套用到 NavigationBar

- NavigationBar 本身為 Row Scope，會自動處理排列與間距  
- 使用 `forEachIndexed` 迴圈逐一渲染 NavigationBarItem  
- 每個 item 需傳入是否被選取與點擊事件處理  

---

### 控制選取狀態的 State 管理

- 使用 `rememberSaveable` 建立 `selectedItemIndex`  
- 初始值設為 0，代表第一個項目預設被選取  
- 使用 index 比對決定是否為選取狀態  
- 點擊時更新 `selectedItemIndex` 為當前項目 index  

---

### 設定導覽行為（選填）

- 若要實作導覽功能，可使用 NavController 進行畫面跳轉  
- 可根據 item 的 title 或新增 route 屬性作為跳轉依據  
- 此處未實作導覽，僅顯示可加入的實作方式  

---

### 設定 Icon 與 Badge 顯示

- 使用 `BadgedBox` 包裹 Icon，以顯示數字或紅點提示  
- 根據是否選取，顯示 filled 或 outlined icon  
- 若 `badgeCount` 不為 null，顯示數字 badge  
- 若 `hasNews` 為 true，顯示無數字紅點  
- 若兩者皆為 false 或 null，則不顯示 badge  

---

### 設定 Label 顯示文字

- 使用 `label` 參數傳入 Text 顯示項目名稱  
- 可提供使用者清楚畫面定位資訊  

---

### 控制 Label 顯示行為

- `alwaysShowLabel` 預設為 true，所有項目皆顯示文字  
- 設為 false 時，僅選取項目會顯示文字  
- 不建議完全隱藏 label，會降低使用者理解性  

---

### 更新 badge 狀態的方法

- 若點擊某個項目後要移除紅點提示，需更新資料來源  
- 將 `items` 設為可變的 Compose State 清單  
- 更新對應項目的 `hasNews` 或 `badgeCount` 值後重組畫面  



# Terminology
- **Jetpack Compose**：Android 的現代 UI 工具包，用於以聲明式方式構建 UI。  
- **Material 3**：Google 最新的設計系統，提供更新的元件和設計指南。  
- **Bottom Navigation View**：Material 2 中的元件，用於在應用中在三到五個主要目的地之間切換。  
- **Navigation Bar**：Material 3 中替代 Bottom Navigation View 的元件，功能相同。  
- **Scaffold**：Compose 中的佈局容器，支援標準 Material 結構如 topBar、bottomBar、floatingActionButton 等。  
- **Surface**：Compose 元件，用於應用背景色及其他主題屬性。  
- **NavigationBarItem**：Material 3 中表示底部導航列中單一項目的元件。  
- **ImageVector**：Compose 中用於表示向量圖示的資料類型。  
- **Icons.Filled**：Material Icons 套件中填滿樣式的圖示。  
- **Icons.Outlined**：Material Icons 套件中外框樣式的圖示。  
- **Badge**：小圓點或數字，用於提示新消息或通知。  
- **BadgeCount**：用於表示 badge 上顯示的數字，如未讀訊息數。  
- **hasNews**：布林值，用於決定是否顯示紅點提示。  
- **Composable**：Compose 中的基本建構區塊，用來定義 UI 元件。  
- **RowScope**：Compose 中 Row 元件的範疇，允許放置子元素。  
- **Experimental API**：仍在實驗階段的 API，需特別標記才能使用。  
- **Opt-in Annotation**：標記實驗性 API 的方式，如 `@OptIn(ExperimentalMaterial3Api::class)`。  
- **Navigation Rail**：用於大螢幕裝置的側邊導覽列。  
- **Outlined Icon**：當前未選取的頁面圖示，使用外框樣式。  
- **Filled Icon**：當前選取的頁面圖示，使用填滿樣式。  
- **Theme**：定義整個應用外觀和感覺的樣式集合。  
- **Modifier**：Compose 中用來修改元件行為或外觀的工具。  
- **List**：Kotlin 中的資料結構，用來儲存底部導航項目。  
- **title**：導航項目的文字標籤。  
- **selected**：用於指示目前是否選中該導航項目的狀態。  
- **onClick**：使用者點擊導航項目後觸發的事件處理器。  
- **remember**：Compose 中的狀態保持機制，用來記住值以避免重組重置。  
- **mutableStateOf**：用於建立可變狀態的函式。  
- **NavigationController**：負責處理導航邏輯的控制器。  
- **NavHost**：用於放置不同目的地的容器。  
- **Destination**：應用中的頁面或畫面目標。  
- **MaterialTheme**：提供預設顏色、字型與形狀的主題設置。  
- **SnackbarHost**：用來顯示短暫提示訊息的元件。  
- **TopAppBar**：顯示在畫面頂部的應用列。  
- **BottomAppBar**：用於顯示畫面底部的操作欄。  
- **FloatingActionButton**：懸浮動作按鈕，常用於主要操作。  
- **AppCompat**：舊版 Android 支援庫，Compose 不依賴它。  
- **Navigation Graph**：定義應用中所有導航目的地與路徑的結構。  
- **Single Activity Architecture**：建議的架構，應用只使用一個 Activity。  
- **Kotlin**：Android 開發主要使用的語言，支援函數式和物件導向程式設計。  
- **State Hoisting**：將狀態從子元件提取到父元件管理的做法。  
- **Icon**：Compose 中顯示圖示的元件。  
- **ColorScheme**：Material 3 中管理應用顏色的結構。  
- **AnimatedVisibility**：Compose 中用於製作顯示或隱藏動畫的元件。  
- **NavigationComponent**：Android 官方推薦的導航框架。  
- **Destination Route**：用於唯一標示目的地的字串。  
- **Nullable Type**：可以為 null 的資料型別。  
- **PaddingValues**：定義元件間距用的結構。  
- **MaterialIcons**：Google 提供的官方圖示套件。  
- **Layout**：Compose 中用來排列元件的機制。  
- **UI State**：代表畫面目前所需顯示資料的狀態物件。  
- **Preview**：Compose 中用來預覽 UI 的註解。  
- **@Composable Function**：被 Compose 編譯器識別為 UI 元件的函式。  
- **ScaffoldState**：管理 Scaffold 元件狀態的物件。  
- **CoroutineScope**：用於執行非同步操作的範疇。
- **forEachIndexed**：Kotlin 提供的函式，用於遍歷清單並同時取得索引與項目。  
- **selectedItemIndex**：記錄當前選取項目索引的狀態變數。  
- **rememberSaveable**：Compose 中的狀態保存機制，可在裝置旋轉或配置變更後保留值。  
- **mutableStateOf**：用來創建可變的 Compose 狀態變數。  
- **NavigationBarItem**：Material 3 的底部導航列元件，用來呈現單一項目。  
- **selected**：NavigationBarItem 中用來判斷是否為目前選取項目的屬性。  
- **onClick**：使用者點擊導航項目時所觸發的事件。  
- **icon Lambda**：NavigationBarItem 的 icon 屬性，透過 Lambda 指定顯示內容。  
- **BadgedBox**：用於顯示徽章（badge）在圖示旁邊的容器。  
- **badge Lambda**：BadgedBox 中用來定義徽章內容的區塊。  
- **Image**：Compose 用來顯示圖片或圖示的元件。  
- **contentDescription**：為無障礙支援所提供的圖示描述文字。  
- **Text**：Compose 中的文字顯示元件。  
- **item.selectedIcon**：目前選取狀態下顯示的圖示資源。  
- **item.unselectedIcon**：未選取狀態下顯示的圖示資源。  
- **item.badgeCount**：徽章所顯示的數字（例如未讀訊息數）。  
- **item.hasNews**：布林值，用來判斷是否顯示無數字的紅點。  
- **label Lambda**：NavigationBarItem 的文字標籤設定區塊。  
- **alwaysShowLabel**：決定是否始終顯示文字標籤的屬性。  
- **state hoisting**：將狀態提升至父元件以便統一管理的設計模式。  
- **NavController**：Jetpack Navigation 元件，用於處理導航邏輯的控制器。  
- **navigate()**：NavController 的函式，用來切換到其他畫面。  
- **route**：Jetpack Navigation 中目的地的唯一識別字串。  
- **comment out**：將程式碼暫時停用的註解操作。  
- **if-else 條件式**：用來依據條件顯示不同 UI 的邏輯控制。  
- **Lambda 表達式**：Kotlin 的函式語法，用於簡潔地定義邏輯區塊。  
- **Composable scope**：Compose 中允許撰寫 UI 元件的範疇。  
- **UI recomposition**：當狀態變更時，自動重新繪製 UI 的過程。  
- **mutableStateListOf**：可變的 Compose 清單狀態，用於動態更新清單內容。  
- **List state**：一個持有整體列表資料的狀態容器。  
- **state update**：改變狀態的動作以觸發 UI 更新。  
- **Icon toggle**：根據狀態變化切換圖示的行為。  
- **Unselected state**：元件目前未被選中的狀態。  
- **Selected state**：元件目前已被選中的狀態。  
- **Configuration changes**：如裝置旋轉等變更，可能導致 Activity 重新建立。  
- **Import statements**：引入外部函式或類別所需的語法。  
- **ViewModel**：Android 架構元件之一，用來儲存和管理 UI 相關資料。  
- **Jetpack Navigation**：Android 官方提供的導航架構。  
- **Material Guidelines**：Google 提供的 UI/UX 設計準則。  
- **Filled icon**：實心圖示，常用於代表當前所在位置。  
- **Outlined icon**：空心圖示，常用於非當前頁面的圖示表示。  
- **State-driven UI**：根據狀態自動更新的使用者介面設計原則。  
- **Accessibility support**：為視障等用戶提供友善介面的設計考量。  
- **Contextual action**：針對特定頁面或狀態所提供的操作選項。  
- **Snackbar**：短暫出現的提示訊息元件，常見於操作回饋。  
- **Jetpack Compose Scaffold**：提供結構化 UI 框架的組件，整合 topBar、bottomBar 等。  
- **Composable parameters**：Compose 函式可接受的參數，如 icon、label。  
- **LazyColumn**：Compose 中可懶加載的垂直清單元件。  
- **NavigationHost**：Jetpack Navigation 的畫面容器，用來載入各個目的地。  
- **@Composable**：標示此函式可用於 Compose UI 的註解。  
- **@Preview**：允許在 Android Studio 預覽 Compose 元件的註解。  
- **MaterialTheme.typography**：Material 主題中的字型樣式設定。  
- **modifier.padding()**：為元件添加間距的修飾器函式。  
- **Icons.Default**：預設圖示集合，常用於快速存取標準圖示。