본문 바로가기
개발 관련 이야기

Android Navigation action 사용하기

by 꿈틀쓰 2022. 10. 30.

지난 번 글에서는 간단한 Navigation의 사용법에 대해서 알아봤다.

 

Android Navigation 사용하기

정말 단순한 작업을 하는 앱이거나 게임이 아닌 이상 대부분의 앱에서 내비게이션바를 쉽게 발견할 수 있을 것이다. 이번에 회사에서 작업하는 앱도 내비게이션 메뉴가 있어야 하는데 Material Com

koomtle-world.tistory.com

 

이 글은 Java를 기준으로 설명합니다.
기본적인 사용법은 위 링크를 봐주세요.

 

 

아직도 내비게이션의 늪에서 빠져나오지 못한 나는 아직도 화면 전환에서 고생 중이다ㅠ

 

 

 

 

메인 메뉴 Menu1, Menu2에서 이동 가능한 공통의 하위 화면 Common이 있다. Common은 각 메뉴에서 파라미터를 받아 그 값으로 적절한 데이터를 서버에서 가져와 출력한다.

 

화면 Menu화면과 Common 사이에는 Master-Detail의 관계가 성립한다. Common 혼자서는 존재할 수 없기 때문이다.

이런 경우에는 어떻게 해야 할까?

 

 

 

 

 

 

Fragment 간의 값 전달?


action을 사용하면 Fragment 간의 값 전달이 용이하다.

 

대상으로 이동  |  Android 개발자  |  Android Developers

대상으로 이동 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 대상으로 이동하는 것은 NavController 객체를 사용하여 실행되며 이 객체는 NavHost 내에서 앱 탐

developer.android.com

 

Bundle을 사용하는 방법도 있는데, 이것보다는 타입을 명확하게 해주는 Safe Args를 사용하기로 하였다.

 

 

 

1. 라이브러리 추가

 

우선 최상위 build.gradlebuildscript를 추가한다.

buildscript {
    repositories {
        google()
    }
    dependencies {
        def nav_version = "2.5.2"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}

위 코드 블럭을 plugins 블럭 위에 위치시킨다. 그렇지 않으면 에러가 난다.. (gradle은 언제나 어려워 ㅠㅠ)

 

 

그 다음 app 레벨의 build.gradleplugins에 다음을 추가한다.

plugins {
  id 'androidx.navigation.safeargs'
}

 

 

 

 

2. action 연결하기

 

간단한 예시를 위해서 fragment_home에서 fragment_secondhome으로 이동하는 코드를 짜보자.

 

mobile_navigation.xml

<?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/home"
    app:startDestination="@id/navigation_home">

    <fragment
        android:id="@+id/navigation_home"
        android:name="com.songworld.bottomnavex.ui.home.HomeFragment"
        android:label="@string/title_home"
        tools:layout="@layout/fragment_home">
        <action
            android:id="@+id/action_home"
            app:destination="@+id/navigation_secondhome" />
    </fragment>

    <fragment
        android:id="@+id/navigation_secondhome"
        android:name="com.songworld.bottomnavex.ui.home.SecondHomeFragment"
        android:label="SecondHome"
        tools:layout="@layout/fragment_secondhome" />

</navigation>

home 화면에서 second_home으로 화면 전환을 하라는 action을 정의하였다. 

navigation_home의 코드 안에 

이렇게만 정의하면 fragment_home에서 fragment_secondhome으로 이동은 가능하나 파라미터가 무엇인지 알 수 없다.

 

 

argument를 추가해보자.

<?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/home"
    app:startDestination="@id/navigation_home">

    <fragment
        android:id="@+id/navigation_home"
        android:name="com.songworld.bottomnavex.ui.home.HomeFragment"
        android:label="@string/title_home"
        tools:layout="@layout/fragment_home">
        <action
            android:id="@+id/action_home"
            app:destination="@+id/navigation_secondhome" >
            <argument
                android:name="myArg"
                app:argType="integer"
                android:defaultValue="1" />
        </action>
    </fragment>

    <fragment
        android:id="@+id/navigation_secondhome"
        android:name="com.songworld.bottomnavex.ui.home.SecondHomeFragment"
        android:label="SecondHome"
        tools:layout="@layout/fragment_secondhome">
        <argument
                android:name="myArg"
                app:argType="integer"
                android:defaultValue="1" />
    </fragment>

</navigation>

name으로 해당 argument 이름을 정의하고,

argType으로 해당 argument타입을 정의하고,

defaultValue으로 해당 argument기본값을 정의한다.

 

 

 

3. 이벤트 등록하기

 

이제 fragment_home에서 버튼을 클릭했을 때 fragment_secondhome으로 action_home의 action을 수행하라는 명령을 내려줘야 한다.

 

안드로이드 공식문서를 보면 SafeArgs의 클래스는 Fragment의 이름으로 정의된다.

발신 -> 수신 Fragment를 우리는 HomeFragment, SecondHomeFragment라고 각각 명명하였다.

 

 

발신에서는,
HomeFragmentDirections 클래스가 자동 생성되고,

수신에서는,
SecondHomeArgs 클래스가 자동 생성된다.

 

 

 

HomeFragment에서 버튼 클릭 이벤트를 다음과 같이 정의하였다.

 

binding.button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                HomeFragmentDirections.ActionHome action = HomeFragmentDirections.actionHome();
                action.setMyArg(11);
                Navigation.findNavController(view).navigate(action);
            }
        });

defaultValuemobile_navigation.xml에서 정의하지 않으면 HomeFragmentDirections.actionHome(11); 과 같이 액션 메소드 내에 바로 argument를 정의해주어야 한다.

 

 

이제 SecondHomeFragment에서 받아보자.

int myarg = SecondHomeFragmentArgs.fromBundle(getArguments()).getMyArg();

onCreatView에서 받을 argument를 저장해주고 자신의 로직에 활용한다.

 

 

 

왼쪽이 Home, go버튼을 클릭해 오른쪽 SecondHome으로 이동하여 전달받은 argument 11을 출력하였다.

 

 

 

 

SafeArgs를 활용하여 손쉽게 navigation에서의 값 전달을 구현해보았다.

조금만 더 고생하면 안드로이드 그만할 수 있겠지???

비 안드로이드 개발자의 고생일지 오늘도 끝

댓글