본문 바로가기
Programming 개발은 구글로/JAVA[Android]

[안드로이드] BottomNavigationView로 하단 바 만들기

by 40대직장인 2022. 4. 19.

BottomNavigationView

: 많은 애플리케이션에서 많이 보이는 Material Design 중 하나가 Bottom Navigation이다. BottomNavigationView는 하단에 바 형태의 메뉴를 생성하여 사용자에게 인터페이스(UI)를 제공하고 있습니다.

 

BottomNavigationView를 Bottom Tab이라고 하시며 TabLayout 대신 사용하시는 분들이 있는데 Tab과 Navigation에는 역할적으로 많은 차이가 있습니다.

 

구글에서도 BottomNavigationView에는 TabLayout과 달리 Swipe 해서 화면을 넘기는 것을 권장하지 않고 있습니다.

 

NavigarionView를 구성할 때에는 Fragment라는 UI 컴포넌트를 사용합니다. Fragment는 별도의 라이프 사이클을 가지며 여러 Activity에서 재사용이 가능합니다.

 

BottomNavigationView 예시 이미지
BottomNavigationView 예시

 

1. build.gradle (Module: app) 수정

 
implementation 'com.android.support:design:28.0.0'

 

build.gradle(Module: BottomNavigation.app) 파일을 열어 dependencies에 한 줄을 추가해준다.

 

2. Menu Resource 추가

2-1. 새로운 menu resource directory를 만들어준다.

  • res(우클릭) > New > Android Resource Directory

2-2. 만들어진 menu resource directory에 main_menu_bottom.xml 파일을 추가한다.

  • (우클릭) > New > Menu Resource File

  • main_menu_bottom 추가

  • /res/menu/main_menu_bottom.xml

 

♣ item은 3~5개를 권장합니다.

 

3. 하단 바를 생성할 Main Activity 추가

3-1. 아이콘의 색상을 책임질 리소스 파일 생성 (생략 가능) 

  • drawble(우클릭) > New > Drawble Resource File

  • menu_item_color 추가

  • res/drawable/menu_item_color.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="true" android:color="#000000"/>
    <item android:state_checked="false" android:color="#A6A6A6"/>
</selector>

 

♣ 아이콘을 클릭했을 때와 클릭하지 않았을 때의 색깔을 다르게 하여 사용자가 보기 편하게 합니다

 

3-2. Main Activity 추가 및 xml 레이아웃 리소스 작성

  • res/layout/activity_main.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/menu_frame_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="?attr/actionBarSize"/>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/menu_bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:itemIconTint="@drawable/menu_item_color"
        app:itemTextColor="@drawable/menu_item_color"
        app:labelVisibilityMode="labeled"
        app:layout_constraintBottom_toBottomOf="parent"
        app:menu="@menu/main_menu_bottom"/>

</androidx.constraintlayout.widget.ConstraintLayout>

 

app:labelVisibilityMode 속성을 labeled로 하면 아이콘 밑에 텍스트가 보입니다.

 

app:itemIconTint="@drawable/menu_item_color" app:itemTextColor="@drawable/menu_item_color" 속성을 통해 아이콘과 텍스트의 색깔을 변경할 수 있습니다.

 

4. 메뉴에서 보여줄 Fragment 추가

  • New > Fragment > Fragment(blank)

 

MainMenuChartFragment, MainMenuSearchFragment, MainMenuMoreFragment 추가

 

4-1. xml 레이아웃 리소스 작성

  • res/layout/fragment_main_menu_chart.xml
<?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"
    tools:context=".MainMenuChartFragment">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="차트"
        android:textColor="@android:color/black"
        android:textSize="50sp"/>

</LinearLayout>
  • res/layout/fragment_main_menu_search.xml
<?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"
    tools:context=".MainMenuSearchFragment">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="검색"
        android:textColor="@android:color/black"
        android:textSize="50sp"/>

</LinearLayout>
  • res/layout/fragment_main_menu_more.xml
<?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"
    tools:context=".MainMenuMoreFragment">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="더보기"
        android:textColor="@android:color/black"
        android:textSize="50sp"/>

</LinearLayout>

4-2. Fragment의 java 파일 작성

  • MainMenuChartFragment.java
public class MainMenuChartFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.fragment_main_menu_chart, 
        						 container, false);

        return rootView;
    }
}
  • MainMenuMoreFragment.java
public class MainMenuMoreFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.fragment_main_menu_more, 
        						 container, false);

        return rootView;
    }
}
  • MainMenuSearchFragment.java
public class MainMenuSearchFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup)inflater.inflate(R.layout.fragment_main_menu_search, 
        						 container, false);

        return rootView;
    }
}

 

5. Fragment와 Menu 연결

  • MainActivity.java
public class MainActivity extends AppCompatActivity {

        private FragmentManager fragmentManager = getSupportFragmentManager();
        private MainMenuChartFragment fragmentChart = new MainMenuChartFragment();
        private MainMenuSearchFragment fragmentSearch = new MainMenuSearchFragment();
        private MainMenuMoreFragment fragmentMore = new MainMenuMoreFragment();

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

            FragmentTransaction transaction = fragmentManager.beginTransaction();
            transaction.replace(R.id.menu_frame_layout, fragmentChart).commitAllowingStateLoss();

            BottomNavigationView bottomNavigationView = findViewById(R.id.menu_bottom_navigation);
            bottomNavigationView.setOnNavigationItemSelectedListener(new ItemSelectedListener());

        }

        class ItemSelectedListener implements BottomNavigationView.OnNavigationItemSelectedListener {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                FragmentTransaction transaction = fragmentManager.beginTransaction();

                switch (menuItem.getItemId()) {
                    case R.id.menu_chart:
                        transaction.replace(R.id.menu_frame_layout, fragmentChart).commitAllowingStateLoss();
                        break;
                    case R.id.menu_search:
                        transaction.replace(R.id.menu_frame_layout, fragmentSearch).commitAllowingStateLoss();
                        break;
                    case R.id.menu_more:
                        transaction.replace(R.id.menu_frame_layout, fragmentMore).commitAllowingStateLoss();
                        break;

                }

                return true;
            }
        }
}

 

 

 

 

 

댓글