Divide and Conquer

navigation backstack 본문

성장캐/안드로이드 스튜디오

navigation backstack

10살 2022. 4. 9. 04:49
728x90
<action
            android:id="@+id/action_nav_slideshow_to_nav_calendar"
            app:destination="@id/nav_calendar"
            app:popUpTo="@layout/fragment_gallery"
            app:popUpToInclusive="false"/>

nav_calendar가 나올 때까지 백 스택을 저장

2. popUpToInclusive 속성이 false이거나 설정되지 않은 경우, popUpTo는 지정된 도착점까지 모든 도착점들을 제거한다. 하지만 지정된 목적지는 백 스택에 들어있다.
3. popUpToInclusive 속성이 true인 경우, popUpTo 속성은 주어진 목적지를 포함해서 모든 목적지들을 백 스택에서 제거한다.
4. popUpToInclusive 속성이 true이고 popUpTo가 앱의 시작점으로 설정된 경우, action은 백 스택의 모든 도착점을 제거한다. 백 버튼을 누르면 바로 앱을 종료한다.

<?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/mobile_navigation"
    app:startDestination="@+id/nav_home">

    <fragment
        android:id="@+id/nav_home"
        android:name="com.example.myapplication.ui.home.HomeFragment"
        android:label="@string/menu_home"
        tools:layout="@layout/fragment_home" >

        <action
            android:id="@+id/action_nav_home_to_nav_gallery"
            app:destination="@id/nav_gallery" />
    </fragment>

    <fragment
        android:id="@+id/nav_gallery"
        android:name="com.example.myapplication.ui.gallery.GalleryFragment"
        android:label="@string/menu_gallery"
        tools:layout="@layout/fragment_gallery" >

        <action
            android:id="@+id/action_nav_gallery_to_nav_slideshow"
            app:destination="@id/nav_slideshow" />
    </fragment>

    <fragment
        android:id="@+id/nav_slideshow"
        android:name="com.example.myapplication.ui.slideshow.SlideshowFragment"
        android:label="@string/menu_slideshow"
        tools:layout="@layout/fragment_slideshow">

        <action
            android:id="@+id/action_nav_slideshow_to_nav_calendar"
            app:destination="@id/nav_calendar"
            app:popUpTo="@layout/fragment_gallery"
            app:popUpToInclusive="false"/>
    </fragment>

    <fragment
        android:id="@+id/nav_calendar"
        android:name="com.example.myapplication.ui.calendar.CalendarFragment"
        android:label="calendar"
        tools:layout="@layout/fragment_calendar" />
</navigation>
navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
            @Override
            public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {
                switch (destination.getId()){
                    case R.id.nav_home:
                        binding.appBarMain.fab.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                navController.navigate(R.id.action_nav_home_to_nav_gallery);
                            }
                        });
                        return;

                    case R.id.nav_gallery:
                        binding.appBarMain.fab.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                navController.navigate(R.id.action_nav_gallery_to_nav_slideshow);
                            }
                        });
                        return;

                    case R.id.nav_slideshow:
                        binding.appBarMain.fab.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                navController.navigate(R.id.action_nav_slideshow_to_nav_calendar);
                            }
                        });
                        return;
                    default:
                        binding.appBarMain.fab.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                                        .setAction("Action", null).show();
                            }
                        });

                        return;
                } // END Switch
            } // END onDestinationChanged
        }); // End addOnDes
        NavigationUI.setupWithNavController(navigationView, navController);
Log.d("TAG", "Call stack", new Throwable("get stacks"));
더보기

1. 액션의 popUpTo 속성은 주어진 도착점(destination)이 나올 때까지 백 스택을 팝업한다.

2. popUpToInclusive 속성이 false이거나 설정되지 않은 경우, popUpTo는 지정된 도착점까지 모든 도착점들을 제거한다. 하지만 지정된 목적지는 백 스택에 들어있다.
3. popUpToInclusive 속성이 true인 경우, popUpTo 속성은 주어진 목적지를 포함해서 모든 목적지들을 백 스택에서 제거한다.
4. popUpToInclusive 속성이 true이고 popUpTo가 앱의 시작점으로 설정된 경우, action은 백 스택의 모든 도착점을 제거한다. 백 버튼을 누르면 바로 앱을 종료한다.

상황 1

진행 : A →B →D →A →C →D

C→D 액션에 popUpTo를 BlankFragment2로 지정하고
D에서 백 버튼을 누르면 어떻게 될까?

B로 돌아간다. (A → B)
이 상태에서 두 번 백 버튼을 누르면 종료된다.

상황 2

진행 : A →C →D →A →C →D

백 스택이 있기 때문에 C에서 백 버튼을 누르면 A로 돌아간다. C가 B에서 왔는지 A에 왔는지를 백 스택으로 확인할 수 있다.

C→D 액션에 popUpTo를 BlankFragment2로 지정하고
D에서 백 버튼을 누르면 어떻게 될까?

백 스택에 BlankFragment2가 들어있지 않기 때문에 그냥 popUpTo 옵션이 지정되어 있지 않은 상황과 같이 동작한다. 바로 전 C로 돌아간다.

상황 3

진행 : A →B →D →A →B →D

B →D 액션에 popUpTo를 BlankFragment로 지정하고
마지막 D에서 백 버튼을 누르면 어떻게 될까?

화면은 A로 바뀐다. 이 A는 A →B →D →A의 마지막 A이다.
여기서 백 버튼을 누르면 D로 돌아가고, (A →B →D)
또 백 버튼을 누르면 B가 아니라 A로 돌아가는데 이것은 B →D 액션의 popUpTo가 BlankFragment로 지정되어 있기 때문이다.
또 백 버튼을 누르면 종료된다.

상황 4

진행 : A →B →D →A →B →D

B →D 액션에 popUpTo를 BlankFragment로 지정하고
popUpToInclusive를 true로 한 상태에서,
마지막 D에서 백 버튼을 누르면 어떻게 될까?

상황 4의 경우

원칙 4에 의해서 백 스택에 모든 도착점들이 사라진다. 화면은 그대로 D를 나타내고 있고, 이 상태에서 백 버튼을 누르면 앱이 종료된다.

참고: https://developer.android.com/guide/navigation/navigation-getting-started

출처: https://taej0127.medium.com/android-navigation-pop-up-c799c7d19d28

반응형
Comments