mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-23 04:00:53 -05:00
scrollable and nonscrollable tabs
This commit is contained in:
@@ -17,6 +17,9 @@ import com.google.accompanist.pager.ExperimentalPagerApi
|
|||||||
import com.google.accompanist.pager.HorizontalPager
|
import com.google.accompanist.pager.HorizontalPager
|
||||||
import com.google.accompanist.pager.PagerState
|
import com.google.accompanist.pager.PagerState
|
||||||
import com.google.accompanist.pager.rememberPagerState
|
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.AccountTabNavItem
|
||||||
import com.owenlejeune.tvtime.ui.navigation.ListFetchFun
|
import com.owenlejeune.tvtime.ui.navigation.ListFetchFun
|
||||||
import com.owenlejeune.tvtime.ui.navigation.MainNavItem
|
import com.owenlejeune.tvtime.ui.navigation.MainNavItem
|
||||||
@@ -57,9 +60,10 @@ fun AccountTabContent(
|
|||||||
) {
|
) {
|
||||||
val contentItems = listFetchFun()
|
val contentItems = listFetchFun()
|
||||||
|
|
||||||
|
if (contentItems.isNotEmpty() && contentItems[0] is RatedTopLevelMedia) {
|
||||||
LazyColumn(modifier = Modifier.fillMaxWidth().padding(12.dp)) {
|
LazyColumn(modifier = Modifier.fillMaxWidth().padding(12.dp)) {
|
||||||
items(contentItems.size) { i ->
|
items(contentItems.size) { i ->
|
||||||
val ratedItem = contentItems[i]
|
val ratedItem = contentItems[i] as RatedTopLevelMedia
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
@@ -85,11 +89,27 @@ fun AccountTabContent(
|
|||||||
modifier = Modifier.height(80.dp),
|
modifier = Modifier.height(80.dp),
|
||||||
verticalArrangement = Arrangement.SpaceBetween
|
verticalArrangement = Arrangement.SpaceBetween
|
||||||
) {
|
) {
|
||||||
Text(text = ratedItem.title, color = MaterialTheme.colorScheme.onBackground, fontSize = 18.sp)
|
Text(
|
||||||
|
text = ratedItem.name,
|
||||||
|
color = MaterialTheme.colorScheme.onBackground,
|
||||||
|
fontSize = 18.sp
|
||||||
|
)
|
||||||
|
|
||||||
Text(text = ratedItem.releaseDate, color = MaterialTheme.colorScheme.onBackground)
|
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)
|
Text(
|
||||||
|
text = "Rating: ${(ratedItem.rating * 10).toInt()}%",
|
||||||
|
color = MaterialTheme.colorScheme.onBackground
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import com.owenlejeune.tvtime.ui.navigation.MainNavItem
|
|||||||
import com.owenlejeune.tvtime.ui.navigation.MediaFetchFun
|
import com.owenlejeune.tvtime.ui.navigation.MediaFetchFun
|
||||||
import com.owenlejeune.tvtime.ui.navigation.MediaTabNavItem
|
import com.owenlejeune.tvtime.ui.navigation.MediaTabNavItem
|
||||||
import com.owenlejeune.tvtime.ui.screens.MediaViewType
|
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 com.owenlejeune.tvtime.ui.screens.tabs.top.Tabs
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
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
|
else -> throw IllegalArgumentException("Media type given: ${mediaType}, \n expected one of MediaViewType.MOVIE, MediaViewType.TV") // shouldn't happen
|
||||||
}
|
}
|
||||||
val pagerState = rememberPagerState()
|
val pagerState = rememberPagerState()
|
||||||
Tabs(tabs = tabs, pagerState = pagerState)
|
ScrollableTabs(tabs = tabs, pagerState = pagerState)
|
||||||
MediaTabs(
|
MediaTabs(
|
||||||
tabs = tabs,
|
tabs = tabs,
|
||||||
pagerState = pagerState,
|
pagerState = pagerState,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Spacer
|
|||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material.ScrollableTabRow
|
||||||
import androidx.compose.material.Tab
|
import androidx.compose.material.Tab
|
||||||
import androidx.compose.material.TabRow
|
import androidx.compose.material.TabRow
|
||||||
import androidx.compose.material.TabRowDefaults.tabIndicatorOffset
|
import androidx.compose.material.TabRowDefaults.tabIndicatorOffset
|
||||||
@@ -71,6 +72,54 @@ fun Tabs(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalPagerApi::class)
|
||||||
|
@Composable
|
||||||
|
fun ScrollableTabs(
|
||||||
|
tabs: List<TabNavItem>,
|
||||||
|
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
|
@Composable
|
||||||
private fun SmallTabIndicator(
|
private fun SmallTabIndicator(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
|||||||
Reference in New Issue
Block a user