文章目錄
- 1、準備工作
- 1.1 參考
- 1.2 依賴添加:
- 1.3 主要控件
- NavigationBar
- HorizontalPager、VerticalPager
- 2、功能描述:
- 3、實現過程
- 3.1 創建一個數據類
- 3.2 創建一個list變量
- 3.3 具體實現
- 3.3.1 創建共享的Pager狀態
- 3.3.2 將頁面索引與頁面標題同步
- 3.3.3 創建協程作用域
- 3.3.4 使用HorizontalPager實現滑動效果
- 代碼實現注意點
- 4、關鍵點
- 4.1 狀態管理重構?:
- 4.2 滑動與導航同步?
1、準備工作
1.1 參考
組件BottomNavigation實現,版本變更后,Material 3 引入了 NavigationBar 作為 BottomNavigation 的替代品,提供更符合現代設計規范的外觀和功能,使用使用 NavigationBar + NavigationBarItem進行實現。
1.2 依賴添加:
使用Bom的版本為2024.04.01,詳細介紹見官網
1.3 主要控件
NavigationBar
NavigationBar 實現在一個應用程序的主要目的地之間移動
@Composable
fun NavigationBar(modifier: Modifier = Modifier,containerColor: Color = NavigationBarDefaults.containerColor,contentColor: Color = MaterialTheme.colorScheme.contentColorFor(containerColor),tonalElevation: Dp = NavigationBarDefaults.Elevation,windowInsets: WindowInsets = NavigationBarDefaults.windowInsets,content: @Composable RowScope.() -> Unit
)
HorizontalPager、VerticalPager
HorizontalPager控制控件左右移動,VerticalPager控制控件上下移動
@Composable
fun HorizontalPager(state: PagerState,modifier: Modifier = Modifier,contentPadding: PaddingValues = PaddingValues(0.dp),pageSize: PageSize = PageSize.Fill,beyondViewportPageCount: Int = PagerDefaults.BeyondViewportPageCount,pageSpacing: Dp = 0.dp,verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,flingBehavior: TargetedFlingBehavior = PagerDefaults.flingBehavior(state = state),userScrollEnabled: Boolean = true,reverseLayout: Boolean = false,key: ((index: Int) -> Any)? = null,pageNestedScrollConnection: NestedScrollConnection = PagerDefaults.pageNestedScrollConnection(state,Orientation.Horizontal),snapPosition: SnapPosition = SnapPosition.Start,pageContent: @Composable PagerScope.(page: Int) -> Unit
2、功能描述:
在底部導航欄中設置按鈕,點擊按鈕切換頁面,或者將頁面左右滑動
如圖所示:
3、實現過程
3.1 創建一個數據類
data class FileBean(val icon:Int = -1,val title:String = "",
)
3.2 創建一個list變量
bottomNavigationList 變量聲明需要的icon和title內容
val bottomNavigationList =mutableListOf(FileBean(icon = R.mipmap.icon_home_page,title = stringResource(R.string.home_text)),FileBean(icon = R.mipmap.icon_case_page,title = stringResource(R.string.case_text)),FileBean(icon = R.mipmap.icon_evidence_page,title = stringResource(R.string.evidence_text)),FileBean(icon = R.mipmap.icon_request_page,title = stringResource(R.string.request_text)),FileBean(icon = R.mipmap.icon_my_page,title = stringResource(R.string.my_text)),)
3.3 具體實現
3.3.1 創建共享的Pager狀態
val pagerState = rememberPagerState(pageCount = { bottomNavigationList.size })
3.3.2 將頁面索引與頁面標題同步
val currentPageTitle by remember {derivedStateOf {bottomNavigationList[pagerState.currentPage].title}}
3.3.3 創建協程作用域
val coroutineScope = rememberCoroutineScope()
3.3.4 使用HorizontalPager實現滑動效果
val pagerState = rememberPagerState(pageCount = { bottomNavigationList.size })val currentPageTitle by remember {derivedStateOf {bottomNavigationList[pagerState.currentPage].title}}val coroutineScope = rememberCoroutineScope()
Scaffold(bottomBar = {NavigationBar(containerColor = Color.White) {bottomNavigationList.forEachIndexed { index, item ->NavigationBarItem(icon = {Icon(painter = painterResource(id = item.icon),contentDescription = item.title)},label = { Text(item.title) },selected = currentPageTitle == item.title,onClick = {// 點擊導航項時平滑滾動到對應頁面coroutineScope.launch {pagerState.animateScrollToPage(index)}},colors = NavigationBarItemDefaults.colors(indicatorColor = Color.Transparent,selectedIconColor = colorResource(R.color.agree_red),selectedTextColor = colorResource(R.color.agree_red),unselectedIconColor = colorResource(R.color.agree_grey),unselectedTextColor = colorResource(R.color.agree_grey),))}}}) { paddingValues ->//使用HorizontalPager實現滑動效果HorizontalPager(state = pagerState,modifier = Modifier.padding(paddingValues),verticalAlignment = Alignment.Top,beyondViewportPageCount = 0 //正常會預加載下一頁,但是頁面復雜會導致性能下降,將其設置為0) { pageIndex ->// 根據當前頁面索引顯示對應內容when (pageIndex) {0 -> HomePage()1 -> FilePage()2 -> VideoPage()3 -> RequestPage()4 -> MyPage()}}}
代碼實現注意點
beyondViewportPageCount 字段
需要注意的是,使用HorizontalPager時會自動加載下一頁,如果每一頁面較為復雜的話,會影響性能,可以通過beyondViewportPageCount 字段控制頁面的加載效果,但是會影響滑動的流暢度,可以選擇進行設置。
4、關鍵點
4.1 狀態管理重構?:
使用 rememberPagerState 統一管理頁面狀態
通過 derivedStateOf 自動同步頁面索引和標題
4.2 滑動與導航同步?
// 點擊導航項時滾動到對應頁面
onClick = {coroutineScope.launch {pagerState.animateScrollToPage(index)}
}// HorizontalPager自動更新當前頁面索引
HorizontalPager(state = pagerState) { pageIndex ->// 顯示對應頁面
}