mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-12-27 01:51:17 -05:00
add bottom navigation
This commit is contained in:
@@ -55,9 +55,12 @@ dependencies {
|
|||||||
implementation Dependencies.AndroidX.ktxCore
|
implementation Dependencies.AndroidX.ktxCore
|
||||||
implementation Dependencies.Compose.ui
|
implementation Dependencies.Compose.ui
|
||||||
implementation Dependencies.Compose.material3
|
implementation Dependencies.Compose.material3
|
||||||
|
implementation Dependencies.Compose.material
|
||||||
implementation Dependencies.Compose.uiToolingPreview
|
implementation Dependencies.Compose.uiToolingPreview
|
||||||
implementation Dependencies.Lifecycle.runtime
|
implementation Dependencies.Lifecycle.runtime
|
||||||
implementation Dependencies.Compose.activity
|
implementation Dependencies.Compose.activity
|
||||||
|
implementation Dependencies.Compose.accompanistSystemUi
|
||||||
|
implementation Dependencies.Compose.navigation
|
||||||
testImplementation Dependencies.Testing.junit
|
testImplementation Dependencies.Testing.junit
|
||||||
androidTestImplementation Dependencies.Testing.androidXJunit
|
androidTestImplementation Dependencies.Testing.androidXJunit
|
||||||
androidTestImplementation Dependencies.Testing.espressoCore
|
androidTestImplementation Dependencies.Testing.espressoCore
|
||||||
|
|||||||
@@ -3,11 +3,19 @@ package com.owenlejeune.tvtime
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.material.Scaffold
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
import androidx.navigation.compose.NavHost
|
||||||
|
import androidx.navigation.compose.composable
|
||||||
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import com.owenlejeune.tvtime.ui.components.*
|
||||||
import com.owenlejeune.tvtime.ui.theme.TVTimeTheme
|
import com.owenlejeune.tvtime.ui.theme.TVTimeTheme
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
@@ -22,10 +30,56 @@ class MainActivity : ComponentActivity() {
|
|||||||
@Composable
|
@Composable
|
||||||
fun MyApp() {
|
fun MyApp() {
|
||||||
TVTimeTheme {
|
TVTimeTheme {
|
||||||
Surface(
|
val navController = rememberNavController()
|
||||||
modifier = Modifier.fillMaxSize()
|
Scaffold(
|
||||||
|
backgroundColor = MaterialTheme.colorScheme.background,
|
||||||
|
bottomBar = { Navbar(navController) }
|
||||||
) {
|
) {
|
||||||
|
NavigationRoutes(navController = navController)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun Navbar(navController: NavController) {
|
||||||
|
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||||
|
val currentRoute = navBackStackEntry?.destination?.route
|
||||||
|
NavigationBar {
|
||||||
|
NavItems.Items.forEachIndexed { index, item ->
|
||||||
|
NavigationBarItem(
|
||||||
|
icon = { Icon(painter = painterResource(id = item.icon), contentDescription = null) },
|
||||||
|
label = { Text(item.name) },
|
||||||
|
selected = currentRoute == item.route,
|
||||||
|
onClick = {
|
||||||
|
navController.navigate(item.route) {
|
||||||
|
navController.graph.startDestinationRoute?.let { screenRoute ->
|
||||||
|
popUpTo(screenRoute) {
|
||||||
|
saveState = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
launchSingleTop = true
|
||||||
|
restoreState = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun NavigationRoutes(navController: NavHostController) {
|
||||||
|
NavHost(navController = navController, startDestination = NavItems.Movies.route) {
|
||||||
|
composable(NavItems.Movies.route) {
|
||||||
|
MoviesTab()
|
||||||
|
}
|
||||||
|
composable(NavItems.TV.route) {
|
||||||
|
TvTab()
|
||||||
|
}
|
||||||
|
composable(NavItems.Favourites.route) {
|
||||||
|
FavouritesTab()
|
||||||
|
}
|
||||||
|
composable(NavItems.Settings.route) {
|
||||||
|
SettingsTab()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.owenlejeune.tvtime.ui.components
|
||||||
|
|
||||||
|
import com.owenlejeune.tvtime.R
|
||||||
|
|
||||||
|
sealed class NavItems(val name: String, val icon: Int, val route: String) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val Items = listOf(Movies, TV, Favourites, Settings)
|
||||||
|
}
|
||||||
|
|
||||||
|
object Movies: NavItems("Movies", R.drawable.ic_movie, "movies_route")
|
||||||
|
object TV: NavItems("TV", R.drawable.ic_tv, "tv_route")
|
||||||
|
object Favourites: NavItems("Favourites", R.drawable.ic_favorite, "favourites_route")
|
||||||
|
object Settings: NavItems("Settings", R.drawable.ic_settings, "settings_route")
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package com.owenlejeune.tvtime.ui.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.wrapContentSize
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun MoviesTab() {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.wrapContentSize(Alignment.Center)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Movies Tab",
|
||||||
|
color = Color.White
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TvTab() {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.wrapContentSize(Alignment.Center)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "TV Tab",
|
||||||
|
color = Color.White
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun FavouritesTab() {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.wrapContentSize(Alignment.Center)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Favourites Tab",
|
||||||
|
color = Color.White
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SettingsTab() {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.wrapContentSize(Alignment.Center)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Settings Tab",
|
||||||
|
color = Color.White
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
package com.owenlejeune.tvtime.ui.theme
|
package com.owenlejeune.tvtime.ui.theme
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.material3.darkColorScheme
|
|
||||||
import androidx.compose.material3.lightColorScheme
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
|
|
||||||
private val DarkColorPalette = darkColorScheme(
|
private val DarkColorPalette = darkColorScheme(
|
||||||
primary = Purple200,
|
primary = Purple200,
|
||||||
@@ -28,15 +29,27 @@ private val LightColorPalette = lightColorScheme(
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TVTimeTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
|
fun TVTimeTheme(
|
||||||
val colors = if (darkTheme) {
|
isDarkTheme: Boolean = isSystemInDarkTheme(),
|
||||||
DarkColorPalette
|
isDynamicColor: Boolean = true,
|
||||||
} else {
|
content: @Composable () -> Unit) {
|
||||||
LightColorPalette
|
val dynamicColor = isDynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
||||||
|
val colorScheme = when {
|
||||||
|
dynamicColor && isDarkTheme -> {
|
||||||
|
dynamicDarkColorScheme(LocalContext.current)
|
||||||
|
}
|
||||||
|
dynamicColor && !isDarkTheme -> {
|
||||||
|
dynamicLightColorScheme(LocalContext.current)
|
||||||
|
}
|
||||||
|
isDarkTheme -> DarkColorPalette
|
||||||
|
else -> LightColorPalette
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val systemUiController = rememberSystemUiController()
|
||||||
|
systemUiController.setStatusBarColor(colorScheme.background, !isDarkTheme)
|
||||||
|
|
||||||
MaterialTheme(
|
MaterialTheme(
|
||||||
colorScheme = colors,
|
colorScheme = colorScheme,
|
||||||
typography = Typography,
|
typography = Typography,
|
||||||
content = content
|
content = content
|
||||||
)
|
)
|
||||||
|
|||||||
9
app/src/main/res/drawable/ic_favorite.xml
Normal file
9
app/src/main/res/drawable/ic_favorite.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/ic_movie.xml
Normal file
9
app/src/main/res/drawable/ic_movie.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M18,4l2,4h-3l-2,-4h-2l2,4h-3l-2,-4H8l2,4H7L5,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V4h-4z"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/ic_settings.xml
Normal file
9
app/src/main/res/drawable/ic_settings.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/ic_tv.xml
Normal file
9
app/src/main/res/drawable/ic_tv.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M21,3L3,3c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h5v2h8v-2h5c1.1,0 1.99,-0.9 1.99,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM21,17L3,17L3,5h18v12z"/>
|
||||||
|
</vector>
|
||||||
@@ -9,10 +9,13 @@ object Dependencies {
|
|||||||
|
|
||||||
object Compose {
|
object Compose {
|
||||||
const val material3 = "androidx.compose.material3:material3:${Versions.compose_material3}"
|
const val material3 = "androidx.compose.material3:material3:${Versions.compose_material3}"
|
||||||
|
const val material = "androidx.compose.material:material:${Versions.compose}"
|
||||||
const val ui = "androidx.compose.ui:ui:${Versions.compose}"
|
const val ui = "androidx.compose.ui:ui:${Versions.compose}"
|
||||||
const val uiToolingPreview = "androidx.compose.ui:ui-tooling-preview:${Versions.compose}"
|
const val uiToolingPreview = "androidx.compose.ui:ui-tooling-preview:${Versions.compose}"
|
||||||
const val uiTooling = "androidx.compose.ui:ui-tooling:${Versions.compose}"
|
const val uiTooling = "androidx.compose.ui:ui-tooling:${Versions.compose}"
|
||||||
const val activity = "androidx.activity:activity-compose:${Versions.activity_compose}"
|
const val activity = "androidx.activity:activity-compose:${Versions.activity_compose}"
|
||||||
|
const val accompanistSystemUi = "com.google.accompanist:accompanist-systemuicontroller:${Versions.compose_accompanist}"
|
||||||
|
const val navigation = "androidx.navigation:navigation-compose:${Versions.compose_navigation}"
|
||||||
}
|
}
|
||||||
|
|
||||||
object Lifecycle {
|
object Lifecycle {
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ object Versions {
|
|||||||
const val ktlint = "0.43.2"
|
const val ktlint = "0.43.2"
|
||||||
const val compose = "1.1.0-rc03"
|
const val compose = "1.1.0-rc03"
|
||||||
const val compose_material3 = "1.0.0-alpha04"
|
const val compose_material3 = "1.0.0-alpha04"
|
||||||
|
const val compose_accompanist = "0.22.1-rc"
|
||||||
|
const val compose_navigation = "2.4.0"
|
||||||
const val gradle = "7.1.0"
|
const val gradle = "7.1.0"
|
||||||
const val junit = "4.13.2"
|
const val junit = "4.13.2"
|
||||||
const val androidx_junit = "1.1.3"
|
const val androidx_junit = "1.1.3"
|
||||||
|
|||||||
Reference in New Issue
Block a user