Compose 实现一个底部Tab的app首页

主要使用 HorizontalPager 、BottomNavigation、BottomNavigationItem

@ExperimentalComposeUiApi
@ExperimentalFoundationApi
@ExperimentalPagerApi
@Composable
fun HomePage() {
    val viewModel: HomeViewModel = viewModel()
    val pageState = rememberPagerState(
        pageCount = listTabItems.size,
        initialPage = viewModel.selectIndex.value,
        initialOffscreenLimit = 2 // 预加载2页
    )
    Column {
        HorizontalPager(
            state = pageState,
            dragEnabled = false, // 不允许左右滑动
            modifier = Modifier.weight(1.0f)
        ) { page ->
            when (page) {
                0 -> InputGluPage()
                1 -> StatisticsPage()
                2 -> SettingsPage()
            }
        }
        BottomNavigationView(pageState)
    }
}

val listTabItems = listOf("首页", "统计", "设置")

@ExperimentalPagerApi
@Composable
fun BottomNavigationView(pageState: PagerState) {
    val viewModel: HomeViewModel = viewModel()
    val scope = rememberCoroutineScope()
    BottomNavigation(backgroundColor = MaterialTheme.colors.background) {
        listTabItems.forEachIndexed { index, label ->
            BottomNavigationItem(
                label = {
                    Text(
                        text = label,
                        color = if (viewModel.selectIndex.value == index) MaterialTheme.colors.primary else Color.Gray
                    )
                },
                selected = index == viewModel.selectIndex.value,
                onClick = {
                    scope.launch {
                        viewModel.selectIndex.value = index
                        pageState.scrollToPage(index)
                    }
                },
                icon = {
                    when (index) {
                        0 -> BottomIcon(Icons.Filled.Home, viewModel.selectIndex.value == index)
                        1 -> BottomIcon(Icons.Filled.Favorite, viewModel.selectIndex.value == index)
                        2 -> BottomIcon(Icons.Filled.Settings, viewModel.selectIndex.value == index)

                    }
                })
        }
    }
}

@Composable
fun BottomIcon(imageVector: ImageVector, isSelected: Boolean) {
    Icon(
        imageVector = imageVector,
        contentDescription = null,
        tint = if (isSelected) MaterialTheme.colors.primary else Color.Gray
    )
}
posted @ 2021-12-05 21:19  用户72093285  阅读(538)  评论(0)    收藏  举报