Skip to content

Instantly share code, notes, and snippets.

@Debdutta-Panda
Created June 4, 2022 17:02
Show Gist options
  • Save Debdutta-Panda/ae836b56759b13b7e030411232c422de to your computer and use it in GitHub Desktop.
Save Debdutta-Panda/ae836b56759b13b7e030411232c422de to your computer and use it in GitHub Desktop.
Bottom Navigation in jetpack Compose
package com.debduttapanda.powernavigation
import androidx.annotation.StringRes
import androidx.compose.animation.AnimatedContentScope
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.Group
import androidx.compose.material.icons.filled.Person
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import com.google.accompanist.navigation.animation.AnimatedNavHost
import com.google.accompanist.navigation.animation.composable
import com.google.accompanist.navigation.animation.rememberAnimatedNavController
sealed class Screen(val route: String, @StringRes val resourceId: Int) {
object Profile : Screen("profile", R.string.profile)
object FriendsList : Screen("friendslist", R.string.friends_list)
}
val items = listOf(
Screen.Profile,
Screen.FriendsList,
)
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun BottomNavigationScreen(){
val navController1 = rememberAnimatedNavController()
Scaffold(
bottomBar = {
BottomNavigation(
backgroundColor = Color(0xfff44336),
contentColor = Color.White
) {
val navBackStackEntry by navController1.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
items.forEach { screen ->
BottomNavigationItem(
icon = { Icon(getIcon(screen), contentDescription = null) },
label = { Text(stringResource(screen.resourceId)) },
selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true,
onClick = {
navController1.navigate(screen.route) {
// Pop up to the start destination of the graph to
// avoid building up a large stack of destinations
// on the back stack as users select items
popUpTo(navController1.graph.findStartDestination().id) {
saveState = true
}
// Avoid multiple copies of the same destination when
// reselecting the same item
launchSingleTop = true
// Restore state when reselecting a previously selected item
restoreState = true
}
}
)
}
}
}
) { innerPadding ->
AnimatedNavHost(navController1, startDestination = Screen.Profile.route, Modifier.padding(innerPadding)) {
composable(
Screen.Profile.route,
enterTransition = {
slideIntoContainer(AnimatedContentScope.SlideDirection.Left, animationSpec = tween(700))
},
exitTransition = {
slideOutOfContainer(AnimatedContentScope.SlideDirection.Left, animationSpec = tween(700))
},
popEnterTransition = {
slideIntoContainer(AnimatedContentScope.SlideDirection.Right, animationSpec = tween(700))
},
popExitTransition = {
slideOutOfContainer(AnimatedContentScope.SlideDirection.Right, animationSpec = tween(700))
}
) { Profile(navController1) }
composable(
Screen.FriendsList.route,
enterTransition = {
slideIntoContainer(AnimatedContentScope.SlideDirection.Left, animationSpec = tween(700))
},
exitTransition = {
slideOutOfContainer(AnimatedContentScope.SlideDirection.Left, animationSpec = tween(700))
},
popEnterTransition = {
slideIntoContainer(AnimatedContentScope.SlideDirection.Right, animationSpec = tween(700))
},
popExitTransition = {
slideOutOfContainer(AnimatedContentScope.SlideDirection.Right, animationSpec = tween(700))
}
) { FriendList(navController1) }
}
}
}
fun getIcon(screen: Screen): ImageVector {
return when(screen.route){
"profile"->Icons.Filled.Person
"friendslist"->Icons.Filled.Group
else->Icons.Filled.Favorite
}
}
@Composable
fun Profile(navController1: NavHostController) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
){
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(
imageVector = Icons.Filled.Person,
contentDescription = "Person",
modifier = Modifier.size(200.dp),
tint = Color(0xfff44336)
)
Text(
"Profile",
color = Color(0xfff44336),
fontSize = 24.sp,
fontWeight = FontWeight.Bold
)
}
}
}
@Composable
fun FriendList(navController1: NavHostController) {
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
){
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(
imageVector = Icons.Filled.Group,
contentDescription = "FriendList",
modifier = Modifier.size(200.dp),
tint = Color(0xfff44336)
)
Text(
"Profile",
color = Color(0xfff44336),
fontSize = 24.sp,
fontWeight = FontWeight.Bold
)
}
}
}
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk 32
defaultConfig {
applicationId "com.debduttapanda.powernavigation"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion compose_version
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
implementation 'androidx.activity:activity-compose:1.3.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
//compose navigation
implementation "androidx.navigation:navigation-compose:2.4.2"
//navigation animation
implementation "com.google.accompanist:accompanist-navigation-animation:0.24.10-beta"
//material icons
implementation "androidx.compose.material:material-icons-extended:$compose_version"
}
package com.debduttapanda.powernavigation
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.ui.Modifier
import com.debduttapanda.powernavigation.ui.theme.PowerNavigationTheme
class MainActivity : ComponentActivity() {
@OptIn(ExperimentalAnimationApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
PowerNavigationTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
BottomNavigationScreen()
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment