[안드로이드/JAVA] 탐색(navigation) NavHostFragment 와 BottomNavigationView 구현하기

구글 Developers 문서 - 탐색 구성 요소

구글 관련 부분 링크 : https://developer.android.com/guide/navigation?hl=ko


* 목표 : navigation (탐색) 기능을 NavHostFragmentBottomNavigationView 를 이용하여 기본 개념을 익히고 구현해보자.


* 구현 영상 



* 나의 개발 설정

 1. Android Studio : 4.1.2 ( 3.3 이상 )

 2. JDK : 8.251 ( 8 이상 )

 3. Android SDK : 29 (30 이상)

 4. Android Gradle Plugin Version : 4.1.2

 5. Gradle Version : 6.5



* 필요한 리소스

 1. res/menu/

   (1) res/menu/bottom_navigation_menu.xml : BottomNavigationM 의 menu 

       


 2. res/navigation

   (1) res/navigation/navigation_main.xml : 이 프로젝트의 navigation 의 main

   (2) res/navigation/navigation_program.xml : BottomNavigationView 의 '트레이닝' 메뉴에서 '프로그램 이동' 버튼을 클릭 했을 때 navigation

   (3) res/navigation/navigation_list.xml : BottomNavigationView 의 '트레이닝' 메뉴에서 '목록 이동' 버튼을 클릭 했을 때 navigation


 3. res/layout

   (1) res/layout/activity_main.xml : NavHostFragment 와 BottmNavigationView 가 있는 main Activity 

   (2) res/layout/fragment_home.xml : BottomNavigationView 의 '홈' 메뉴를 눌렀을 때 표시되는 Fragment

   (3) res/layout/fragment_training.xml : BottomNavigationView 의 '트레이닝' 메뉴를 눌렀을 때 표시되는 Fragment

   (4) res/layout/fragment_more_info.xml : BottomNavigationView 의 '더보기' 메뉴를 눌렀을 때 표시되는 Fragment

   (5) res/layout/fragment_program.xml : BottomNavigationView 의 '트레이닝' 화면에서 '프로그램 이동' 버튼을 클릭 했을 때 표시되는 Fragment

   (6) res/layout/fragment_list.xml : BottomNavigationView 의 '트레이닝' 화면에서 '목록 이동' 버튼을 클릭 했을 때 표시되는 Fragment



 4. java

   (1) 각 Activity 와 Fragment 

 


 


* 그림으로 이해하기

 1. main activity layout 배치



 2. navigation 과 bottom navigation 을 id 로 연결하기



 3. navigation 에 fragment 배치



 4. navigation 에서 action 의 사용법



 5. 코드) NavHostFragment 와 BottomNavigationView 객체 가져오기



 6. 코드) NavHostFragment 와 BottomNavigationView 연결하기 



 7. 백 스택 관리 





* Navigation 의 Fragment 추가 방법 

 1.  navigation 파일 만들기


 
 2. Fragment 추가하기
 


 3. 시작 Fragment 정하기




 4. action 추가하기




 5. navigation xml 파일 연결하기 /  해당 xml 파일에서 시작하는 Fragment 정하기





* 코드

 1. [main activity] activity_main.xml 
   
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
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
 
        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/A_main_nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            app:defaultNavHost="true"
            app:navGraph="@navigation/navigation_main" />
 
        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/A_main_bottom_navigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:menu="@menu/bottom_navigation_menu" />
    </LinearLayout>
 
</androidx.constraintlayout.widget.ConstraintLayout>
cs


 2. [main activity] MainActivity

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
public class MainActivity extends AppCompatActivity {
 
    // constant
    private static final String TAG = MainActivity.class.getSimpleName();
 
    // instance variable : widget
    private NavHostFragment navHostFragment;
    private BottomNavigationView bottomNavigationView;
 
    // instance variable
    private NavController navController;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.A_main_nav_host_fragment);
 
        bottomNavigationView = findViewById(R.id.A_main_bottom_navigation);
 
        navController = navHostFragment.getNavController();
 
        NavigationUI.setupWithNavController(bottomNavigationView, navController);
 
    }
 
 
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        return NavigationUI.onNavDestinationSelected(item, navController) || super.onOptionsItemSelected(item);
    }
 
    @Override
    public void onBackPressed() {
 
        // 현재 화면 가져오기
        NavDestination navDestination = navController.getCurrentDestination();
 
        // 현재 화면이 home 화면이면 종료 alert dialog 표시
        if (navDestination.getId() == R.id.navGraphHomeFragment) {
 
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle(R.string.A_main_Alert_finish_title)
                    .setMessage(R.string.A_main_Alert_finish_message)
                    .setPositiveButton(R.string.A_main_Alert_finish_Btn_positive, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                        }
                    })
                    .setNegativeButton(R.string.A_main_Alert_finish_Btn_negative, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.cancel();
                        }
                    })
                    .show();
        } else {
 
            navController.popBackStack();
        }
 
    }
 
}
cs

 3. [Navigation] navigation_main.xml 

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
31
32
33
34
35
36
37
<?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/navigation_project"
    app:startDestination="@id/navGraphHomeFragment">
 
    <fragment
        android:id="@+id/navGraphHomeFragment"
        android:name="com.skymanlab.navexam.Fragment.HomeFragment"
        android:label="fragment_home"
        tools:layout="@layout/fragment_home" />
 
    <fragment
        android:id="@+id/navGraphTrainingFragment"
        android:name="com.skymanlab.navexam.Fragment.TrainingFragment"
        android:label="fragment_training"
        tools:layout="@layout/fragment_training">
        <action
            android:id="@+id/action_navGraphMoreInfoFragment_to_navigationProgram"
            app:destination="@id/navigationProgram" />
        <action
            android:id="@+id/action_navGraphMoreInfoFragment_to_navigationList"
            app:destination="@id/navigationList" />
    </fragment>
 
    <fragment
        android:id="@+id/navGraphMoreInfoFragment"
        android:name="com.skymanlab.navexam.Fragment.MoreInfoFragment"
        android:label="fragment_more_info"
        tools:layout="@layout/fragment_more_info" />
 
    <include app:graph="@navigation/navigation_list" />
 
    <include app:graph="@navigation/navigation_program" />
 
</navigation>
cs


4. [Navigation] navigation_program.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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/navigationProgram"
    app:startDestination="@id/navGraphProgramFragment">
 
    <fragment
        android:id="@+id/navGraphProgramFragment"
        android:name="com.skymanlab.navexam.Fragment.training.ProgramFragment"
        android:label="fragment_program"
        tools:layout="@layout/fragment_program" />
</navigation>
cs


5. [Navigation] navigation_list.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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/navigationList"
    app:startDestination="@id/navGraphListFragment">
 
    <fragment
        android:id="@+id/navGraphListFragment"
        android:name="com.skymanlab.navexam.Fragment.training.ListFragment"
        android:label="fragment_list"
        tools:layout="@layout/fragment_list" />
</navigation>
cs


6. [bottom menu] bottom_navigation_menu.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
 
    <item
        android:title="@string/Menu_bottom_navigation_menu_title_home"
        android:id="@+id/navGraphHomeFragment"
        android:icon="@drawable/bottom_navigation_menu_icon_home"/>
    <item
        android:title="@string/Menu_bottom_navigation_menu_title_training"
        android:id="@+id/navGraphTrainingFragment"
        android:icon="@drawable/bottom_navigation_menu_icon_training"/>
    <item
        android:title="@string/Menu_bottom_navigation_menu_title_more_info"
        android:id="@+id/navGraphMoreInfoFragment"
        android:icon="@drawable/bottom_navigation_menu_icon_more_info"/>
</menu>
cs


* 코드 링크 





댓글

이 블로그의 인기 게시물

[App] 당구 데이터 - 애플리케이션 소개

[App] Weight Training - 애 애플리케이션 소개