Operator: tabs in the Library view should feel swipeable, not just tappable. Replace the selectedTab Int state + when-block content with HorizontalPager whose state drives the PrimaryScrollableTabRow. Tap routes through animateScrollToPage so swipe + tap share one source of truth. Horizontal pager gestures don't conflict with the LazyVerticalGrid inside each tab (different axes) or with PullToRefreshScaffold's vertical pull (different axes). HorizontalPager renders only the current page by default; adjacent tabs remain composed during the swipe but not eager-mounted at start.
This commit is contained in:
@@ -4,7 +4,6 @@ package com.fabledsword.minstrel.library.ui
|
||||
|
||||
import androidx.compose.animation.Crossfade
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
@@ -12,6 +11,8 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.grid.GridCells
|
||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
||||
import androidx.compose.foundation.lazy.grid.items
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
@@ -22,11 +23,10 @@ import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.launch
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.navigation.NavHostController
|
||||
@@ -69,8 +69,12 @@ fun LibraryScreen(
|
||||
navController: NavHostController,
|
||||
viewModel: LibraryViewModel = hiltViewModel(),
|
||||
) {
|
||||
var selectedTab by remember { mutableIntStateOf(0) }
|
||||
val tabs = LIBRARY_TABS
|
||||
// HorizontalPager owns the active-tab state — the TabRow reads
|
||||
// pagerState.currentPage and animateScrollToPage drives it on tap,
|
||||
// so swipe and tap stay in sync.
|
||||
val pagerState = rememberPagerState(pageCount = { tabs.size })
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
@@ -91,13 +95,13 @@ fun LibraryScreen(
|
||||
},
|
||||
)
|
||||
PrimaryScrollableTabRow(
|
||||
selectedTabIndex = selectedTab,
|
||||
selectedTabIndex = pagerState.currentPage,
|
||||
edgePadding = 16.dp,
|
||||
) {
|
||||
tabs.forEachIndexed { index, label ->
|
||||
Tab(
|
||||
selected = selectedTab == index,
|
||||
onClick = { selectedTab = index },
|
||||
selected = pagerState.currentPage == index,
|
||||
onClick = { scope.launch { pagerState.animateScrollToPage(index) } },
|
||||
text = { Text(label) },
|
||||
)
|
||||
}
|
||||
@@ -105,8 +109,11 @@ fun LibraryScreen(
|
||||
}
|
||||
},
|
||||
) { inner ->
|
||||
Box(modifier = Modifier.fillMaxSize().padding(inner)) {
|
||||
when (selectedTab) {
|
||||
HorizontalPager(
|
||||
state = pagerState,
|
||||
modifier = Modifier.fillMaxSize().padding(inner),
|
||||
) { page ->
|
||||
when (page) {
|
||||
TAB_ARTISTS -> ArtistsTab(viewModel = viewModel, navController = navController)
|
||||
TAB_ALBUMS -> AlbumsTab(viewModel = viewModel, navController = navController)
|
||||
TAB_HISTORY -> HistoryTab(
|
||||
|
||||
Reference in New Issue
Block a user