본문 바로가기
안드로이드 자바

[Android][JAVA] NavigationBar 이용하여 Fragment 간 이동하기

by teamnova 2024. 8. 29.
728x90

 

안녕하세요 오늘은 안드로이드에서 네비게이션바를 이용하여서

프래그먼트 화면 전환을 해보도록 하겠습니다. 

 

 

 

main_activity.xml 

<?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">

    <FrameLayout
        android:id="@+id/main_layout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" >
    </FrameLayout>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavigationView"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/button_navi_menu"
        app:labelVisibilityMode="labeled"
        app:itemBackground="@color/white"
        app:itemIconTint="@color/black"
        app:itemTextColor="@color/black"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

 

먼저, 메인 화면 Bottom 에 네비게이션 바를 추가해줍니다.

 

 

 

이어서 각 프래그먼트를 나타내는 메뉴는 resource 를 나타내는 res 디렉토리에

Android Resource Directory -> menu 를 선택해 추가해주도록 합니다. 

 

 

button_navi_menu.xml 

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/home"
        android:enabled="true"
        android:icon="@drawable/bmnavi_home4"
        android:title="홈"
        app:showAsAction="always"/>

    <item
        android:id="@+id/mylabrary"
        android:enabled="true"
        android:icon="@drawable/bmnavi_book4"
        android:title="내 서재"
        app:showAsAction="always"/>


    <item
        android:id="@+id/board"
        android:enabled="true"
        android:icon="@drawable/bmnavi_brush4"
        android:title="게시판"
        app:showAsAction="always"/>


    <item
        android:id="@+id/myprofile"
        android:enabled="true"
        android:icon="@drawable/bmnavi_user4"
        android:title="마이페이지"
        app:showAsAction="always"/>



</menu>

 

본 게시글에서는 총 4개의 아이템을 추가할 예정입니다. 

사진은 drawble 디렉토리에 있는 기본 이미지를 사용하시거나 원하는 아이콘을 해당 폴더에 넣어서 사용하시면 됩니다. 

 

 

그리고 총 4개의 아이템에 해당하는 4개의 프레그먼트 파일을 만듭니다. 

 

BlankFragment1.java (~BlankFragment4.java 동일) 

package com.example.fragmentexample0829;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link BlankFragment1#newInstance} factory method to
 * create an instance of this fragment.
 */
public class BlankFragment1 extends Fragment {

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public BlankFragment1() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment BlankFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static BlankFragment1 newInstance(String param1, String param2) {
        BlankFragment1 fragment = new BlankFragment1();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_blank, container, false);
    }
}

 

기존 액티비티와는 조금 다른 구조를 보입니다. 

이곳에 원하는 기능을 추가하시면 됩니다. 보통 bottom 가장 왼쪽에 있는 아이콘에 해당하는 화면은 

유저가 앱에 진입했을때 가장 먼저 맞이하는 홈화면으로 사용됩니다. 

홈화면에 필요한 기능을 추가해주시면 됩니다. 

 

 

프래그먼트를 생성할때에 xml 파일이 자동으로 생성됩니다 

fragment_blank.xml (1~4번 동일) 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".BlankFragment1">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="1번 프래그먼트 입니다"
        android:textSize="30dp"
        />

</LinearLayout>

 

 

 

MainActivity.java

package com.example.fragmentexample0829;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;

import android.os.Bundle;
import android.util.SparseArray;
import android.view.MenuItem;

import com.google.android.material.navigation.NavigationBarView;

public class MainActivity extends AppCompatActivity {


    BlankFragment1 blankFragment1;
    BlankFragment2 blankFragment2;
    BlankFragment3 blankFragment3;
    BlankFragment4 blankFragment4;


// 프래그먼트를 저장하는 배열 SparseArray
    SparseArray<Fragment> fragmentArray = new SparseArray<>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        // view 초기화
        // 네비게이션 바
        NavigationBarView navigationBarView = findViewById(R.id.bottomNavigationView);


        // Fragment를 SparseArray에 저장
        fragmentArray.put(R.id.home, new BlankFragment1());
        fragmentArray.put(R.id.mylabrary, new BlankFragment2());
        fragmentArray.put(R.id.board, new BlankFragment3());
        fragmentArray.put(R.id.myprofile, new BlankFragment4());


        // 초기 Fragment 설정
        getSupportFragmentManager().beginTransaction().replace(R.id.main_layout, fragmentArray.get(R.id.home)).commit();


        // 네비게이션 바 아이템 클릭 이벤트
        navigationBarView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                Fragment selectedFragment = fragmentArray.get(item.getItemId());

                if(selectedFragment !=null) {
                    getSupportFragmentManager().beginTransaction().replace(R.id.main_layout, selectedFragment).commit();
                    return true;
                }
                return false;
            }
        });

    }
}

 

 

본 게시글에서는 SparseArray 를 사용하여 프래그먼트를 관리합니다. 

네비게이션에 선택되는 아이콘에 따라 해당 프래그먼트로 전환됩니다. 

 

 

SparseArray 란? 

안드로이드에서 제공하는 데이터 구조로, 일반적인 해시맵이나 ArrayMap 과 유사하지만 

메모리 효율성을 중시한 구조입니다. 

 

그렇기 때문에 데이터가 약 1000개를 넘어간다거나, 데이터의 삽입, 삭제가 빈번한 경우 

SparseArray 는 내부 배열을 재구성하기 때문에 성능 저하가 발생할 수 있습니다. 

 

 

 

오늘은 네비게이션 바와 프래그먼트 화면 전환을 해보았습니다 ! 감사합니다 !