안드로이드 스튜디오

[안드로이드 스튜디오 코틀린]로그인 후 BottomBar가 있는 홈화면 진입하는 간단 예제 (with Compose)

권송미 2024. 9. 11. 18:25
728x90
반응형

 

 

 

 

이번에 만들어 볼 예제는

 

로그인 화면 -> 바텀바가 있는 홈화면-> 로그아웃이 있는 설정화면 -> 다시 로그인 화면 (바텀바 없이)

 

 

입니다.

 

 

 

 

 

 

 

 

 

 

 

 

-> 로그아웃 버튼을 누르면 다시 바텀바가 없는 login화면으로 이동합니다.

 

 

 

 

 

 

 

 

 

 

우선 build.gradle(app)에 아래를 추가해줍니다.

 

    // NavController 사용을 위한 추가
    implementation 'androidx.navigation:navigation-runtime-ktx:2.7.7'
    implementation 'androidx.navigation:navigation-compose:2.7.7'

    // hiltViewModel() 사용을 위한 추가
    implementation 'androidx.hilt:hilt-navigation-compose:1.0.0'

 

 

 

 

Bottom Bar 생성을 위해 

 

HomeScreen, DetailScreen, SettingScreen 을 생성해줍니다.

 

 

 

 

 

 

 

MainScreen, LoginScreen도 만들어줍니다.

로그인 성공한 Boolean 값 전달을 위한 LoginViewModel까지 생성하여

 

 

 

이렇게 나눠서 만들었습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

HomeScreen, DetailScreen은 아무 내용도 들어가지 않았고,

로그아웃 버튼이 있을 SettingScreen에는 아래처럼 짜주었습니다.

 

 

 

 

SettingScreen.kt

import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.navigation.NavHostController
import com.example.composeloginbottombar.viewmodel.LoginViewModel

@Composable
fun SettingScreen(navHostController: NavHostController, viewModel: LoginViewModel) {
    Button(
        onClick = {
            viewModel.logout()
            navHostController.navigate("login") {
                popUpTo("home") { inclusive = true }
            }
        }
    ) {
        Text("Logout")
    }
}

 

 

 

 

 

 

 

 

 

위의 세 가지 화면을 바텀바로 만들 것이고,

바텀바를 MainScreen의 Scaffold bottombar에 넣기 위해 하나의 함수로 만들었습니다.

 

 

 

BottomNavigationBar.kt

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.List
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBarItem
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.navigation.NavController
import androidx.navigation.compose.currentBackStackEntryAsState

@Composable
fun BottomNavigationBar(navController: NavController) {

    val currentBackStackEntry by navController.currentBackStackEntryAsState()
    val currentRoute = currentBackStackEntry?.destination?.route

    BottomAppBar {
        NavigationBarItem(
            selected = currentRoute == "home",
            onClick = { navController.navigate("home") },
            icon = {
                Icon(imageVector = Icons.Default.Home, contentDescription = "Home")
            }
        )

        NavigationBarItem(
            selected = currentRoute == "detail",
            onClick = { navController.navigate("detail") },
            icon = {
                Icon(imageVector = Icons.Default.List, contentDescription = "Detail")
            }
        )

        NavigationBarItem(
            selected = currentRoute == "setting",
            onClick = { navController.navigate("setting") },
            icon = {
                Icon(imageVector = Icons.Default.Settings, contentDescription = "Setting")
            }
        )
    }
}

 

 

 

 

 

 

이제 로그인 화면인 

 

LoginScreen.kt

import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.navigation.NavController
import com.example.composeloginbottombar.viewmodel.LoginViewModel

@Composable
fun LoginScreen(navController: NavController, viewModel: LoginViewModel) {
    Button(
        onClick = {
        viewModel.login()
        navController.navigate("home") {
            popUpTo("login") { inclusive = true }
        }
    }
    ) {
        Text("Login")
    }
}

 

 

 

 

같이 연결해줄

 

LoginViewModel.kt

import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

class LoginViewModel: ViewModel() {
    private val _isLoggedIn = MutableStateFlow(false)
    val isLoggedIn : StateFlow<Boolean> = _isLoggedIn

    fun login() {
        _isLoggedIn.value = true
    }

    fun logout() {
        _isLoggedIn.value = false
    }
}

 

 

 

 

 

 

 

 

 

 

이제 제일 중요한 화면을 연결해주는 MainScreen입니다.

 

MainScreen.kt

import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import com.example.composeloginbottombar.ui.BottomNavigationBar
import com.example.composeloginbottombar.ui.LoginScreen
import com.example.composeloginbottombar.ui.bottom.DetailScreen
import com.example.composeloginbottombar.ui.bottom.HomeScreen
import com.example.composeloginbottombar.ui.bottom.SettingScreen
import com.example.composeloginbottombar.viewmodel.LoginViewModel

@Composable
fun MainScreen(navController: NavHostController, viewModel: LoginViewModel) {
    val isLoggedIn by viewModel.isLoggedIn.collectAsState()

    Scaffold(
        bottomBar = {
            if (isLoggedIn) {
                BottomNavigationBar(navController = navController)
            }
        }
    ) { paddingValues ->
        NavHost(
            navController = navController,
            startDestination = if (isLoggedIn) "home" else "login",
            modifier = Modifier.padding(paddingValues)
        ) {
            composable("login") { LoginScreen(navController, viewModel) }
            composable("home") { HomeScreen() }
            composable("detail") { DetailScreen() }
            composable("setting") { SettingScreen(navController, viewModel) }
        }
    }
}

 

- 로그인 했을 시에만 Bottombar가 보이게 만들고 싶어 if 문에 isLoggedIn Boolean 값을 넣어주었습니다.

- 아까 만들어두었던 BottomNavigationBar를 Scaffold 안 bottomBar에 넣어줍니다.

 

 

 

 

 

 

 

MainActivity.kt

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.compose.rememberNavController
import com.example.composeloginbottombar.viewmodel.LoginViewModel

class MainActivity : ComponentActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val viewModel: LoginViewModel = hiltViewModel()
            val navController = rememberNavController()
            MainScreen(navController = navController, viewModel = viewModel)
        }
    }
}

 

- MainActivity에서는 MainScreen을 잘 호출해주면 끝입니다 !

 

 

 

 

 

 

 

 

 

 

 

 

 

SettingScreen에 있는 로그아웃 버튼을 누르면 LoginScreen으로 잘 돌아가는 것을 볼 수 있습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

감사합니다 !

 

 

 

 

728x90
반응형