Refactor Page navigation into a ViewPager.
This commit is contained in:
parent
689e0a90e5
commit
0506953d34
8 changed files with 104 additions and 202 deletions
|
|
@ -111,6 +111,8 @@ dependencies {
|
||||||
implementation "com.google.accompanist:accompanist-insets:0.24.7-alpha"
|
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-drawablepainter:0.24.7-alpha"
|
||||||
implementation "com.google.accompanist:accompanist-navigation-material: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
|
// Navigation
|
||||||
implementation "androidx.navigation:navigation-compose:2.4.2"
|
implementation "androidx.navigation:navigation-compose:2.4.2"
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +1,44 @@
|
||||||
package com.pixelized.biblib.ui.screen.home
|
package com.pixelized.biblib.ui.screen.home
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
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.runtime.*
|
||||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clipToBounds
|
import androidx.compose.ui.draw.clipToBounds
|
||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
import androidx.compose.ui.platform.SoftwareKeyboardController
|
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.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.navigation.NavHostController
|
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||||
import androidx.navigation.compose.rememberNavController
|
import com.google.accompanist.pager.HorizontalPager
|
||||||
|
import com.google.accompanist.pager.rememberPagerState
|
||||||
import com.pixelized.biblib.ui.composable.Search
|
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.BottomDetailScaffold
|
||||||
import com.pixelized.biblib.ui.scaffold.SearchScaffold
|
import com.pixelized.biblib.ui.scaffold.SearchScaffold
|
||||||
import com.pixelized.biblib.ui.scaffold.SearchScaffoldState
|
import com.pixelized.biblib.ui.scaffold.SearchScaffoldState
|
||||||
import com.pixelized.biblib.ui.scaffold.rememberSearchScaffoldState
|
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.screen.profile.ProfileScreen
|
||||||
|
import com.pixelized.biblib.ui.theme.BibLibTheme
|
||||||
|
import com.pixelized.biblib.utils.extention.bibLib
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun HomeScreen(
|
fun HomeScreen(
|
||||||
accountViewModel: HomeViewModel = hiltViewModel(),
|
accountViewModel: HomeViewModel = hiltViewModel(),
|
||||||
keyboard: SoftwareKeyboardController? = LocalSoftwareKeyboardController.current,
|
keyboard: SoftwareKeyboardController? = LocalSoftwareKeyboardController.current,
|
||||||
navHostController: NavHostController = rememberNavController(),
|
|
||||||
searchScaffoldState: SearchScaffoldState = rememberSearchScaffoldState(),
|
searchScaffoldState: SearchScaffoldState = rememberSearchScaffoldState(),
|
||||||
) {
|
) {
|
||||||
var pouet: String by remember { mutableStateOf("aucun") }
|
var pouet: String by remember { mutableStateOf("aucun") }
|
||||||
|
|
@ -67,14 +81,7 @@ fun HomeScreen(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
content = {
|
content = {
|
||||||
Column {
|
HomeScreenContent()
|
||||||
HomeTarBar(
|
|
||||||
homePageNavController = navHostController
|
|
||||||
)
|
|
||||||
PageNavHost(
|
|
||||||
navHostController = navHostController,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -82,4 +89,50 @@ fun HomeScreen(
|
||||||
searchScaffoldState.collapse()
|
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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
<!-- Bottom bar -->
|
<!-- Bottom bar -->
|
||||||
|
|
||||||
<string name="menu_new">Nouveautés</string>
|
<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_series">Séries</string>
|
||||||
<string name="menu_author">Auteurs</string>
|
<string name="menu_author">Auteurs</string>
|
||||||
<string name="menu_tag">Étiquettes</string>
|
<string name="menu_tag">Étiquettes</string>
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@
|
||||||
|
|
||||||
<!-- Menu item -->
|
<!-- Menu item -->
|
||||||
|
|
||||||
<string name="menu_new">News</string>
|
<string name="menu_new">What\'s news</string>
|
||||||
<string name="menu_book">Books</string>
|
<string name="menu_book">Library</string>
|
||||||
<string name="menu_series">Series</string>
|
<string name="menu_series">Series</string>
|
||||||
<string name="menu_author">Authors</string>
|
<string name="menu_author">Authors</string>
|
||||||
<string name="menu_tag">tags</string>
|
<string name="menu_tag">Tags</string>
|
||||||
|
|
||||||
<!-- Dialogs -->
|
<!-- Dialogs -->
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue