Refactor Page navigation into a ViewPager.

This commit is contained in:
Thomas Andres Gomez 2022-06-30 18:34:16 +02:00
parent 689e0a90e5
commit 0506953d34
8 changed files with 104 additions and 202 deletions

View file

@ -111,6 +111,8 @@ dependencies {
implementation "com.google.accompanist:accompanist-insets:0.24.7-alpha"
implementation "com.google.accompanist:accompanist-drawablepainter:0.24.7-alpha"
implementation "com.google.accompanist:accompanist-navigation-material:0.24.7-alpha"
implementation "com.google.accompanist:accompanist-pager:0.24.7-alpha"
implementation "com.google.accompanist:accompanist-pager-indicators:0.24.7-alpha"
// Navigation
implementation "androidx.navigation:navigation-compose:2.4.2"

View file

@ -1,47 +0,0 @@
package com.pixelized.biblib.ui.navigation.page
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.ui.graphics.vector.ImageVector
import com.pixelized.biblib.R
sealed class Page(
val route: String,
val icon: ImageVector,
@StringRes val label: Int,
) {
object News : Page(
route = "news",
icon = Icons.Default.NewReleases,
label = R.string.menu_new,
)
object Books : Page(
route = "books",
icon = Icons.Default.AutoStories,
label = R.string.menu_book,
)
object Series : Page(
route = "series",
icon = Icons.Default.AutoAwesomeMotion,
label = R.string.menu_series,
)
object Author : Page(
route = "author",
icon = Icons.Default.SupervisorAccount,
label = R.string.menu_author,
)
object Tag : Page(
route = "tag",
icon = Icons.Default.LocalOffer,
label = R.string.menu_tag,
)
companion object {
val all = listOf(News, Books, Series, Author, Tag)
}
}

View file

@ -1,47 +0,0 @@
package com.pixelized.biblib.ui.navigation.page
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.pixelized.biblib.ui.screen.home.page.books.BooksPage
import com.pixelized.biblib.ui.screen.home.page.news.NewsPage
val LocalPageNavHostController = compositionLocalOf<NavHostController> {
error("LocalHomePageNavHostController is not ready yet.")
}
@Composable
fun PageNavHost(
modifier: Modifier = Modifier,
navHostController: NavHostController = rememberNavController(),
startDestination: Page = Page.News
) {
CompositionLocalProvider(LocalPageNavHostController provides navHostController) {
NavHost(
modifier = modifier,
navController = navHostController,
startDestination = startDestination.route,
) {
composable(Page.News.route) {
NewsPage()
}
composable(Page.Books.route) {
BooksPage()
}
composable(Page.Series.route) {
}
composable(Page.Author.route) {
}
composable(Page.Tag.route) {
}
}
}
}

View file

@ -1,30 +1,44 @@
package com.pixelized.biblib.ui.screen.home
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.material.MaterialTheme
import androidx.compose.material.ScrollableTabRow
import androidx.compose.material.Tab
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.SoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.pager.HorizontalPager
import com.google.accompanist.pager.rememberPagerState
import com.pixelized.biblib.ui.composable.Search
import com.pixelized.biblib.ui.navigation.page.PageNavHost
import com.pixelized.biblib.ui.scaffold.BottomDetailScaffold
import com.pixelized.biblib.ui.scaffold.SearchScaffold
import com.pixelized.biblib.ui.scaffold.SearchScaffoldState
import com.pixelized.biblib.ui.scaffold.rememberSearchScaffoldState
import com.pixelized.biblib.ui.screen.home.page.Page
import com.pixelized.biblib.ui.screen.home.page.books.BooksPage
import com.pixelized.biblib.ui.screen.home.page.news.NewsPage
import com.pixelized.biblib.ui.screen.profile.ProfileScreen
import com.pixelized.biblib.ui.theme.BibLibTheme
import com.pixelized.biblib.utils.extention.bibLib
import kotlinx.coroutines.launch
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun HomeScreen(
accountViewModel: HomeViewModel = hiltViewModel(),
keyboard: SoftwareKeyboardController? = LocalSoftwareKeyboardController.current,
navHostController: NavHostController = rememberNavController(),
searchScaffoldState: SearchScaffoldState = rememberSearchScaffoldState(),
) {
var pouet: String by remember { mutableStateOf("aucun") }
@ -67,14 +81,7 @@ fun HomeScreen(
}
},
content = {
Column {
HomeTarBar(
homePageNavController = navHostController
)
PageNavHost(
navHostController = navHostController,
)
}
HomeScreenContent()
},
)
@ -82,4 +89,50 @@ fun HomeScreen(
searchScaffoldState.collapse()
}
}
}
@OptIn(ExperimentalPagerApi::class)
@Composable
fun HomeScreenContent(
pages: List<Page> = Page.all
) {
val scope = rememberCoroutineScope()
val pagerState = rememberPagerState()
Column {
ScrollableTabRow(
selectedTabIndex = pagerState.currentPage,
edgePadding = MaterialTheme.bibLib.dimen.dp16,
) {
// Add tabs for all of our pages
pages.forEachIndexed { index, page ->
Tab(
text = { Text(text = stringResource(id = page.label)) },
selected = pagerState.currentPage == index,
onClick = { scope.launch { pagerState.animateScrollToPage(index) } },
)
}
}
HorizontalPager(
state = pagerState,
count = pages.size
) {
when (pages[it]) {
is Page.News -> NewsPage()
is Page.Books -> BooksPage()
is Page.Author -> Box(modifier = Modifier.fillMaxSize())
is Page.Series -> Box(modifier = Modifier.fillMaxSize())
is Page.Tag -> Box(modifier = Modifier.fillMaxSize())
}
}
}
}
@Composable
@Preview(showBackground = true)
private fun HomeScreenContentPreview() {
BibLibTheme {
HomeScreenContent()
}
}

View file

@ -1,91 +0,0 @@
package com.pixelized.biblib.ui.screen.home
import android.content.res.Configuration
import androidx.compose.foundation.layout.RowScope
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.pixelized.biblib.ui.navigation.page.Page
import com.pixelized.biblib.ui.theme.BibLibTheme
@Composable
fun HomeTarBar(
homePageNavController: NavHostController = rememberNavController(),
pages: List<Page> = Page.all
) {
BottomNavigation(
backgroundColor = MaterialTheme.colors.background,
) {
val navBackStackEntry by homePageNavController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
pages.forEach { page ->
val selected = currentDestination?.hierarchy?.any { it.route == page.route }
BottomNavigationIcon(
page = page,
selected = selected ?: false,
onClick = {
homePageNavController.navigate(page.route) {
// Pop up to the start destination of the graph to avoid building up a
// large stack of destinations on the back stack as users select items
popUpTo(homePageNavController.graph.findStartDestination().id) {
saveState = true
}
// Avoid multiple copies of the same destination when re-selecting the same item
launchSingleTop = true
// Restore state when re-selecting a previously selected item
restoreState = true
}
}
)
}
}
}
@Composable
fun RowScope.BottomNavigationIcon(
modifier: Modifier = Modifier,
page: Page,
selected: Boolean,
selectedColor: Color = MaterialTheme.colors.primary,
defaultColor: Color = MaterialTheme.colors.onSurface,
onClick: () -> Unit = {},
) {
BottomNavigationItem(
modifier = modifier,
icon = {
Icon(
imageVector = page.icon,
contentDescription = null,
)
},
label = {
Text(
style = MaterialTheme.typography.caption,
text = stringResource(id = page.label),
)
},
selectedContentColor = selectedColor,
unselectedContentColor = defaultColor,
selected = selected,
onClick = onClick,
)
}
@Composable
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun BottomBarNavigationPreview() {
BibLibTheme {
HomeTarBar()
}
}

View file

@ -0,0 +1,32 @@
package com.pixelized.biblib.ui.screen.home.page
import androidx.annotation.StringRes
import com.pixelized.biblib.R
sealed class Page(
@StringRes val label: Int,
) {
object News : Page(
label = R.string.menu_new,
)
object Books : Page(
label = R.string.menu_book,
)
object Series : Page(
label = R.string.menu_series,
)
object Author : Page(
label = R.string.menu_author,
)
object Tag : Page(
label = R.string.menu_tag,
)
companion object {
val all = listOf(News, Books, Series, Author, Tag)
}
}

View file

@ -9,7 +9,7 @@
<!-- Bottom bar -->
<string name="menu_new">Nouveautés</string>
<string name="menu_book">Livres</string>
<string name="menu_book">Library</string>
<string name="menu_series">Séries</string>
<string name="menu_author">Auteurs</string>
<string name="menu_tag">Étiquettes</string>

View file

@ -13,11 +13,11 @@
<!-- Menu item -->
<string name="menu_new">News</string>
<string name="menu_book">Books</string>
<string name="menu_new">What\'s news</string>
<string name="menu_book">Library</string>
<string name="menu_series">Series</string>
<string name="menu_author">Authors</string>
<string name="menu_tag">tags</string>
<string name="menu_tag">Tags</string>
<!-- Dialogs -->