add bottom navigation

This commit is contained in:
Owen LeJeune
2022-02-09 16:13:20 -05:00
parent a9e916abb9
commit db37c06ae3
11 changed files with 208 additions and 15 deletions

View File

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

View File

@@ -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()
} }
} }
} }

View File

@@ -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")
}

View File

@@ -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
)
}
}

View File

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

View 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>

View 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>

View 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>

View 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>

View File

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

View File

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