From 70d2afa9c316cc01fc1798f88eef5ea382598ab9 Mon Sep 17 00:00:00 2001 From: Owen LeJeune Date: Wed, 2 Mar 2022 20:54:35 -0500 Subject: [PATCH] scrollable and nonscrollable tabs --- .../ui/screens/tabs/bottom/AccountTab.kt | 80 ++++++++++++------- .../tvtime/ui/screens/tabs/bottom/MediaTab.kt | 3 +- .../tvtime/ui/screens/tabs/top/TabsCommon.kt | 49 ++++++++++++ 3 files changed, 101 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/AccountTab.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/AccountTab.kt index 25deed3..c5dce26 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/AccountTab.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/AccountTab.kt @@ -17,6 +17,9 @@ import com.google.accompanist.pager.ExperimentalPagerApi import com.google.accompanist.pager.HorizontalPager import com.google.accompanist.pager.PagerState import com.google.accompanist.pager.rememberPagerState +import com.owenlejeune.tvtime.api.tmdb.model.RatedMovie +import com.owenlejeune.tvtime.api.tmdb.model.RatedTopLevelMedia +import com.owenlejeune.tvtime.api.tmdb.model.RatedTv import com.owenlejeune.tvtime.ui.navigation.AccountTabNavItem import com.owenlejeune.tvtime.ui.navigation.ListFetchFun import com.owenlejeune.tvtime.ui.navigation.MainNavItem @@ -57,39 +60,56 @@ fun AccountTabContent( ) { val contentItems = listFetchFun() - LazyColumn(modifier = Modifier.fillMaxWidth().padding(12.dp)) { - items(contentItems.size) { i -> - val ratedItem = contentItems[i] + if (contentItems.isNotEmpty() && contentItems[0] is RatedTopLevelMedia) { + LazyColumn(modifier = Modifier.fillMaxWidth().padding(12.dp)) { + items(contentItems.size) { i -> + val ratedItem = contentItems[i] as RatedTopLevelMedia - Row( - horizontalArrangement = Arrangement.spacedBy(8.dp), - modifier = Modifier.clickable( - onClick = { - appNavController.navigate( - "${MainNavItem.DetailView.route}/${mediaViewType}/${ratedItem.id}" + Row( + horizontalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier.clickable( + onClick = { + appNavController.navigate( + "${MainNavItem.DetailView.route}/${mediaViewType}/${ratedItem.id}" + ) + } + ) + ) { + Image( + modifier = Modifier + .width(60.dp) + .height(80.dp), + painter = rememberImagePainter( + data = TmdbUtils.getFullPosterPath(ratedItem.posterPath) + ), + contentDescription = "" + ) + + Column( + modifier = Modifier.height(80.dp), + verticalArrangement = Arrangement.SpaceBetween + ) { + Text( + text = ratedItem.name, + color = MaterialTheme.colorScheme.onBackground, + fontSize = 18.sp + ) + + val date = when (ratedItem) { + is RatedMovie -> ratedItem.releaseDate + is RatedTv -> ratedItem.firstAirDate + else -> "" + } + Text( + text = date, + color = MaterialTheme.colorScheme.onBackground + ) + + Text( + text = "Rating: ${(ratedItem.rating * 10).toInt()}%", + color = MaterialTheme.colorScheme.onBackground ) } - ) - ) { - Image( - modifier = Modifier - .width(60.dp) - .height(80.dp), - painter = rememberImagePainter( - data = TmdbUtils.getFullPosterPath(ratedItem.posterPath) - ), - contentDescription = "" - ) - - Column( - modifier = Modifier.height(80.dp), - verticalArrangement = Arrangement.SpaceBetween - ) { - Text(text = ratedItem.title, color = MaterialTheme.colorScheme.onBackground, fontSize = 18.sp) - - Text(text = ratedItem.releaseDate, color = MaterialTheme.colorScheme.onBackground) - - Text(text = "Rating: ${(ratedItem.rating*10).toInt()}%", color = MaterialTheme.colorScheme.onBackground) } } } diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/MediaTab.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/MediaTab.kt index d74b396..3e35fd0 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/MediaTab.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/bottom/MediaTab.kt @@ -17,6 +17,7 @@ import com.owenlejeune.tvtime.ui.navigation.MainNavItem import com.owenlejeune.tvtime.ui.navigation.MediaFetchFun import com.owenlejeune.tvtime.ui.navigation.MediaTabNavItem import com.owenlejeune.tvtime.ui.screens.MediaViewType +import com.owenlejeune.tvtime.ui.screens.tabs.top.ScrollableTabs import com.owenlejeune.tvtime.ui.screens.tabs.top.Tabs import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -33,7 +34,7 @@ fun MediaTab(appNavController: NavHostController, mediaType: MediaViewType) { else -> throw IllegalArgumentException("Media type given: ${mediaType}, \n expected one of MediaViewType.MOVIE, MediaViewType.TV") // shouldn't happen } val pagerState = rememberPagerState() - Tabs(tabs = tabs, pagerState = pagerState) + ScrollableTabs(tabs = tabs, pagerState = pagerState) MediaTabs( tabs = tabs, pagerState = pagerState, diff --git a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/top/TabsCommon.kt b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/top/TabsCommon.kt index 38c2e8d..c3d4125 100644 --- a/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/top/TabsCommon.kt +++ b/app/src/main/java/com/owenlejeune/tvtime/ui/screens/tabs/top/TabsCommon.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.ScrollableTabRow import androidx.compose.material.Tab import androidx.compose.material.TabRow import androidx.compose.material.TabRowDefaults.tabIndicatorOffset @@ -71,6 +72,54 @@ fun Tabs( } } +@OptIn(ExperimentalPagerApi::class) +@Composable +fun ScrollableTabs( + tabs: List, + pagerState: PagerState, + modifier: Modifier = Modifier, + backgroundColor: Color = MaterialTheme.colorScheme.background, + contentColor: Color = MaterialTheme.colorScheme.primary, + selectedTabTextColor: Color = MaterialTheme.colorScheme.primary, + unselectedTabTextColor: Color = MaterialTheme.colorScheme.onBackground, + tabTextStyle: TextStyle = MaterialTheme.typography.bodySmall, + tabIndicatorColor: Color = MaterialTheme.colorScheme.primary +) { + val scope = rememberCoroutineScope() + + ScrollableTabRow( + modifier = modifier, + selectedTabIndex = pagerState.currentPage, + backgroundColor = backgroundColor, + contentColor = contentColor, + edgePadding = 8.dp, + indicator = { tabPositions -> + SmallTabIndicator( + modifier = Modifier.tabIndicatorOffset(tabPositions[pagerState.currentPage]), + color = tabIndicatorColor + ) + } + ) { + tabs.forEachIndexed { index, tab -> + Tab( + text = { + Text( + text = tab.name, + style = tabTextStyle, + color = if (pagerState.currentPage == index) selectedTabTextColor else unselectedTabTextColor + ) + }, + selected = pagerState.currentPage == index, + onClick = { + scope.launch { + pagerState.animateScrollToPage(index) + } + } + ) + } + } +} + @Composable private fun SmallTabIndicator( modifier: Modifier = Modifier,