scrollable and nonscrollable tabs

This commit is contained in:
Owen LeJeune
2022-03-02 20:54:35 -05:00
parent 3d7314b44d
commit 70d2afa9c3
3 changed files with 101 additions and 31 deletions

View File

@@ -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,39 +60,56 @@ fun AccountTabContent(
) { ) {
val contentItems = listFetchFun() val contentItems = listFetchFun()
LazyColumn(modifier = Modifier.fillMaxWidth().padding(12.dp)) { if (contentItems.isNotEmpty() && contentItems[0] is RatedTopLevelMedia) {
items(contentItems.size) { i -> LazyColumn(modifier = Modifier.fillMaxWidth().padding(12.dp)) {
val ratedItem = contentItems[i] items(contentItems.size) { i ->
val ratedItem = contentItems[i] as RatedTopLevelMedia
Row( Row(
horizontalArrangement = Arrangement.spacedBy(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.clickable( modifier = Modifier.clickable(
onClick = { onClick = {
appNavController.navigate( appNavController.navigate(
"${MainNavItem.DetailView.route}/${mediaViewType}/${ratedItem.id}" "${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)
} }
} }
} }

View File

@@ -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,

View File

@@ -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,