清單/詳細資料是一種 UI 模式,由雙窗格版面配置組成,其中一個窗格會顯示項目清單,另一個窗格則會顯示從清單中選取的項目詳細資料。
此模式特別適合用於提供大型集合元素深入資訊的應用程式,例如電子郵件用戶端,其中包含電子郵件清單和每封電子郵件詳細內容。清單詳細資料也可以用於較不重要的路徑,例如將應用程式偏好設定分割為類別清單,並在詳細資料窗格中列出每個類別的偏好設定。
使用 ListDetailPaneScaffold
實作 UI 模式
ListDetailPaneScaffold
是可組合項,可簡化應用程式中清單/詳細資料模式的實作方式。清單/詳細資料架構最多可包含三個窗格:清單窗格、詳細資料窗格和選用的額外窗格。結構體會處理螢幕空間計算作業。當螢幕尺寸足夠時,系統會在清單窗格旁邊顯示詳細資料窗格。在小螢幕尺寸上,架構會自動切換為全螢幕顯示清單或詳細資料窗格。
宣告依附元件
ListDetailPaneScaffold
是 Material 3 自適應版面配置程式庫的一部分。
將下列三個相關依附元件新增至應用程式或模組的 build.gradle
檔案:
Kotlin
implementation("androidx.compose.material3.adaptive:adaptive") implementation("androidx.compose.material3.adaptive:adaptive-layout") implementation("androidx.compose.material3.adaptive:adaptive-navigation")
Groovy
implementation 'androidx.compose.material3.adaptive:adaptive' implementation 'androidx.compose.material3.adaptive:adaptive-layout' implementation 'androidx.compose.material3.adaptive:adaptive-navigation'
- 自適應:低階構成元素,例如
HingeInfo
和Posture
- adaptive-layout:自動調整式版面配置,例如
ListDetailPaneScaffold
和SupportingPaneScaffold
- adaptive-navigation:用於在窗格內部和之間導覽的可組合項
基本用法
請依照下列方式實作 ListDetailPaneScaffold
:
使用代表所選內容的類別。這個類別應為
Parcelable
,才能支援儲存及還原所選清單項目。使用 kotlin-parcelize 外掛程式產生程式碼。@Parcelize class MyItem(val id: Int) : Parcelable
使用
rememberListDetailPaneScaffoldNavigator
建立ThreePaneScaffoldNavigator
,並新增BackHandler
。這個導覽器可用於在清單、詳細資料和其他窗格之間移動。透過宣告泛型類型,導覽器也會追蹤結構體的狀態 (也就是顯示哪個MyItem
)。由於此類型可分割,因此導覽器可以儲存及還原狀態,自動處理設定變更。BackHandler
支援使用系統返回手勢或按鈕返回。ListDetailPaneScaffold
的返回按鈕預期行為取決於視窗大小和目前的結構區塊值。如果ListDetailPaneScaffold
可支援以目前狀態返回,則canNavigateBack()
為true
,可啟用BackHandler
。val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() }
將
scaffoldState
從navigator
傳遞至ListDetailPaneScaffold
可組合函式。ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, // ... )
將清單窗格實作項目提供給
ListDetailPaneScaffold
。使用AnimatedPane
在瀏覽期間套用預設的窗格動畫。接著,使用ThreePaneScaffoldNavigator
前往詳細資料窗格ListDetailPaneScaffoldRole.Detail
,並顯示傳入的項目。ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = { AnimatedPane { MyList( onItemClick = { item -> // Navigate to the detail pane with the passed item navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item) } ) } }, // ... )
在
ListDetailPaneScaffold
中加入詳細資料窗格實作內容。導覽完成後,currentDestination
會包含應用程式已導覽至的窗格,包括窗格中顯示的內容。content
屬性與原始記住呼叫 (本範例中的MyItem
) 中指定的型別相同,因此您也可以存取需要顯示的任何資料屬性。ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = // ... detailPane = { AnimatedPane { navigator.currentDestination?.content?.let { MyDetails(it) } } }, )
實作上述步驟後,程式碼應如下所示:
val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() } ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = { AnimatedPane { MyList( onItemClick = { item -> // Navigate to the detail pane with the passed item navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item) }, ) } }, detailPane = { AnimatedPane { // Show the detail pane content if selected item is available navigator.currentDestination?.content?.let { MyDetails(it) } } }, )