Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
Tags
- 공유오피스
- 중첩네비게이션
- fragmentcontainer
- 자바
- 패파
- 아키텍쳐
- rxandroid
- 스택
- 파이썬
- Stack
- Android
- 알고리즘
- 너무 어렵다
- innernavigation
- parentfragment
- 안드로이드
- 재밌긴함
- 후기
- 사무실
- Kotlin
- 코틀린
- 가든웨딩
- 백준
- SAA
- media3
- 더베일리하우스 삼성점
- 패스트파이브
- media3 transformer
- MVVM
- 내부프레그먼트
Archives
삽질도사
[안드로이드] jetpack navigation + BottomNavigation 뒤로가기로 홈 화면 가기 본문
SAA 구조를 사용한 형태에서
스플래시 화면 -> (로그인 및 기타 화면) -> 홈화면 -> 다른 화면 -> (뒤로가기 버튼 누름) -> 홈화면
일반적인 경우 이런 비슷한 구조를 채택할텐데, SAA에서 popUpTo 혹은 PopUpInclusive를 알고 사용한다 하더라도
쉽게 떠오르거나 해결되지 않아서(개인적으로..) 매번 생각하느라 고생고생을 한다.
그래서 이러한 구조를 다른 프로젝트에 사용한다던지 혹은 다른 방식으로 구조를 짜더라도 유연하게 생각하기 위해서 이러한 일련의 과정을 기록하기로 했다.
package kr.foorun.uni_eat.feature.main
import androidx.activity.viewModels
import androidx.navigation.NavController
import androidx.navigation.NavDirections
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
import dagger.hilt.android.AndroidEntryPoint
import kr.foorun.presentation.MainNavDirections
import kr.foorun.presentation.R
import kr.foorun.presentation.databinding.ActivityMainBinding
import kr.foorun.uni_eat.base.view.base.context_view.BaseActivity
@AndroidEntryPoint
class MainActivity : BaseActivity<ActivityMainBinding, MainViewModel>({ActivityMainBinding.inflate(it)}){
override val activityViewModel: MainViewModel by viewModels()
private lateinit var navController: NavController
override fun afterBinding() = binding {
setUpBottomNavigationView()
}
override fun observeAndInitViewModel() = binding {
viewModel = activityViewModel.apply {
}
}
private fun setUpBottomNavigationView() = binding {
val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragmentContainerView) as NavHostFragment
navController = navHostFragment.navController
setDestinationListener()
setUpBottomNav()
}
/**
* @setupWithNavController(navController) is to fetch view into frame when click bottom icon
*
* @setOnItemSelectedListener is to make sure action works properly,
* if you use only setupWithNavController, view is not attached on frame when click bottom icon.
*/
private fun setUpBottomNav() = binding {
bottomNav.setupWithNavController(navController) //to fetch view into frame when click bottom icon
bottomNav.setOnItemSelectedListener {//to make sure action works properly if you use
when(it.itemId){
R.id.home_nav -> true.apply { navigate(MainNavDirections.actionToHomeNav()) }
R.id.map_nav -> true.apply { navigate(MainNavDirections.actionToMapNav()) }
R.id.event_nav -> true.apply { navigate(MainNavDirections.actionToEventNav()) }
R.id.article_nav -> true.apply { navigate(MainNavDirections.actionToArticleNav()) }
R.id.my_nav -> true.apply { navigate(MainNavDirections.actionToMyNav()) }
else -> false
}
}
}
private fun navigate(directions: NavDirections) = navController.navigate(directions)
private fun setDestinationListener() = navController.addOnDestinationChangedListener { controller, destination, arg ->
if(arg != null){
if (arg.isEmpty) bottomVisible(true)
else if(arg.getBoolean(getString(R.string.hide_bottom))) bottomVisible(false)
} else bottomVisible(true)
}
fun bottomVisible(isVisible: Boolean) = activityViewModel.setBottomVisible(isVisible)
}
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_nav"
app:startDestination="@id/splash_nav">
<include app:graph="@navigation/article_nav" />
<include app:graph="@navigation/event_nav" />
<include app:graph="@navigation/my_nav" />
<include app:graph="@navigation/map_nav" />
<include app:graph="@navigation/login_nav" />
<include app:graph="@navigation/home_nav" />
<fragment
tools:layout="@layout/fragment_article_detail"
android:id="@+id/article_detail_fragment"
android:name="kr.foorun.uni_eat.feature.article.detail.ArticleDetailFragment"
android:label="ArticleDetailFragment" >
<argument
android:name="@string/hide_bottom"
app:argType="boolean"
android:defaultValue="true" />
</fragment>
<action
app:enterAnim="@anim/from_right"
app:exitAnim="@anim/to_left"
app:popUpToInclusive="true"
app:popUpTo="@id/splash_fragment"
android:id="@+id/action_to_loginFragment"
app:destination="@id/login_nav" />
<action
android:id="@+id/action_to_articleDetailFragment"
app:destination="@id/article_detail_fragment" />
<action
android:id="@+id/action_to_my_nav"
app:popUpTo="@id/home_fragment"
app:popUpToInclusive="false" //bottom navigation에 있는 경우 이것을 false로 해서 home만 남게한다.
app:destination="@id/my_nav" />
<action
android:id="@+id/action_to_map_nav"
app:popUpTo="@id/home_fragment"
app:popUpToInclusive="false" //bottom navigation에 있는 경우 이것을 false로 해서 home만 남게한다.
app:destination="@id/map_nav" />
<action
android:id="@+id/action_to_event_nav"
app:popUpTo="@id/home_fragment"
app:popUpToInclusive="false" //bottom navigation에 있는 경우 이것을 false로 해서 home만 남게한다.
app:destination="@id/event_nav" />
<action
android:id="@+id/action_to_article_nav"
app:popUpTo="@id/home_fragment"
app:popUpToInclusive="false" //bottom navigation에 있는 경우 이것을 false로 해서 home만 남게한다.
app:destination="@id/article_nav" />
<action
app:popUpToInclusive="true"
app:popUpTo="@id/login_fragment"
android:id="@+id/action_to_home_nav"
app:destination="@id/home_nav" />
<include app:graph="@navigation/splash_nav" />
</navigation>
main_nav의 코드인데 이곳에서 액션/화면 을 정의하여 글로벌하게 쓰고 있다.
중요한건 위 코드에서 주석처리한 것처럼 액션을 사용해서 stack에 HomeFragment만 남게 하는 것이 목적이다.
이렇게 사용함으로써 다른 화면(bottom navigation 에 존재하는)에서 뒤로가기를 누르더라도 영상처럼 홈화면으로 갈 수 있다.