Android Studio

Android Studio - BottomNavigationView위젯으로 하단 메뉴탭 만들기

Bubbles 2021. 1. 28. 01:06

최근 졸업작품을 안드로이드 스튜디오 프레임워크를 사용해서 하는 중이라, 필요한 BottomNavigationView내용을 다시 공부할 겸, 나중에 이 정보가 필요한 사람들에게 도움이 되었으면 하는 바람으로 쓰는 포스팅입니다. :D

 

 

우선 안드로이드 스튜디오에서 프로젝트 생성을 해주시고, AppBarLayout을 다운로드 받아주세요. (아래 사진 참고)

 

이미 다운받아놔서 사진엔 다운로드 표시가 없음 

그 다음 하단 메뉴바를 위한 xml파일(activity_main.xml과는 다른 별도의파일)을 만들어 작성해줍니다. 

그러고 나서 따로 menu폴더를 생성하고, new resource file for menu를 통해 파일을 생성해주시면 됩니다.

파일이름은 bottom_menu로 하였습니다.

<?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/first_tab"
        app:showAsAction="always"
        android:enabled="true"
        android:icon="@drawable/write"
        android:title="Write" />
    <item
        android:id="@+id/second_tab"
        app:showAsAction="always"
        android:enabled="true"
        android:icon="@drawable/mapview"
        android:title="Maps"/>

    <item
        android:id="@+id/third_tab"
        app:showAsAction="always"
        android:enabled="true"
        android:icon="@drawable/records"
        android:title="Record">
    </item>

    <item
        android:id="@+id/fourth_tab"
        app:showAsAction="always"
        android:enabled="true"
        android:icon="@drawable/settings"
        android:title="Setting">
    </item>

</menu>

 

코드는 이런식으로 짰는데, 각 <item>이 메뉴 각각의 탭들에 들어갈 항목들을 의미합니다.

 

<#코드부가설명>

▶ app:showAsAction="ture"로 설정해서 항상 보이게끔 해줍니다. 만약 이 값이 "isRoom"이라면 메뉴에 여유공간이 있을 경우에만 항목들을 보여줍니다.

android:icon에서 각 아이콘별로 보여줄 이미지를 설정할 수 있습니다. app\src\main\res\drawable폴더에 원하는 이미지를 미리 넣어두고 사용하시면 됩니다. 

▶ android:title은 아이콘과 함께 메뉴탭에 글씨를 넣을 수 있습니다.

 


다음으로, activity_main.xml파일을 작성해보겠습니다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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/parent_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/container"></FrameLayout>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_menu"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="#345E86"
        app:itemIconTint="#FFFFFF"
        app:itemTextColor="#f6d170"
        app:labelVisibilityMode="labeled"
        app:menu="@menu/bottom_menu"/>

</RelativeLayout>

<#코드부가설명>

app:itemIconTint : 아이콘의 색

app:itemTextColor : 아까 android:title로 설정한 텍스트의 색

app:labelVisibilityMode="labeled" : 현재 menu에 있는 icon개수가 4개이상이므로, 설정한 텍스트가 나오지 않을 수 있습니다. 개수에 상관없이 텍스트를 항상 보이게 하고 싶을 때 labeled로 설정해주면 됩니다. 

app:menu="@menu/bottom_menu" : 아까 위에서 만들어둔 bottom_menu.xml을 메뉴에 넣어줍니다. 

activity_main.xml의 모습입니다. 


그리고 추가적으로, 저는 헤더부분을 하나 만들고 싶어서 위에 RelativeLayout을 추가하고, 이미지를 넣어두었습니다. 

헤더도 위에 넣고, 헤더와 아래 메뉴 사이에 프래그먼트를 띄우시고 싶으신 분들은 아래 코드를 참고하시면 됩니다. 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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/parent_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <RelativeLayout
        android:id="@+id/header"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="#345e86"
        android:layout_alignParentTop="true">

        <ImageView
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:background="@drawable/pinimage"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true">
        </ImageView>

    </RelativeLayout>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/header"
        android:id="@+id/container"></FrameLayout>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_menu"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="#345E86"
        app:itemIconTint="#FFFFFF"
        app:itemTextColor="#f6d170"
        app:labelVisibilityMode="labeled"
        app:menu="@menu/bottom_menu"/>
</RelativeLayout>

결과물

 

 


이제, 각 메뉴 탭을 눌렀을 때, 프래그먼트를 바꿔가며 보여주도록 만들어보겠습니다. 

각 메뉴를 눌렀을 때 보여줄 프래그먼트 4개를 만들어주겠습니다. 

포스팅용이므로 특정 기능을 구현하진 않고 간단하게 색만 다른 프래그먼트들을 만들어주겠습니다. 

 

프래그먼트 생성

#fragment_pink.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:background="#fa9cc5"
    tools:context=".PinkFragment">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Pink Fragment / write">
    </TextView>

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:hint="Name"
        android:inputType="text"
        android:textColorHint="#345e86"></EditText>
</RelativeLayout>

#PinkFragment.java

package org.techtown.underbarmenu;

import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class PinkFragment extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_pink, container, false);
    }
}

 

#fragment_pink의 모습

 

이런식으로 간단하게 만들어주었습니다. 

그리고 나서 MainActivity.java코드를 다음과 같이 수정합니다. 

 

package org.techtown.underbarmenu;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuItem;
import com.google.android.material.bottomnavigation.BottomNavigationView;

public class MainActivity extends AppCompatActivity {
    PinkFragment pinkFragment;
    YellowFragment yellowFragment;
    GreenFragment greenFragment;
    PurpleFragment purpleFragment;

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

        pinkFragment = new PinkFragment();
        yellowFragment = new YellowFragment();
        greenFragment = new GreenFragment();
        purpleFragment = new PurpleFragment();

        getSupportFragmentManager().beginTransaction().replace(R.id.container, pinkFragment).commit();
        BottomNavigationView bottom_menu = findViewById(R.id.bottom_menu);
        bottom_menu.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch(item.getItemId()) {
                    case R.id.first_tab:
                        getSupportFragmentManager().beginTransaction().replace(R.id.container, pinkFragment).commit();
                        return true;
                    case R.id.second_tab:
                        getSupportFragmentManager().beginTransaction().replace(R.id.container, yellowFragment).commit();
                        return true;
                    case R.id.third_tab:
                        getSupportFragmentManager().beginTransaction().replace(R.id.container, greenFragment).commit();
                        return true;
                    case R.id.fourth_tab:
                        getSupportFragmentManager().beginTransaction().replace(R.id.container, purpleFragment).commit();
                        return true;
                }
                return false;
            }
        });
    }
}

switch문에서 각 tab이 선택될 때마다 그에 맞는 fragment를 fragmentManager을 통해 불러오는 방식으로 작동됩니다. 


마지막으로, 휴대폰에 연결하여 테스트 하기 전, AndroidManifest.xml파일에서 변경할 부분이 있습니다. 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.techtown.underbarmenu">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.NoActionBar">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

android:theme이 부분을

android:theme="@style/Theme.AppCompat.NoActionBar"

이렇게 바꿔주셔야 테스트시 맨 위에 뜨는 기본세팅인 초록색 헤더부분이 안 보입니다. 

 


아래는 제 핸드폰으로 테스트 해 본 결과입니다. 

각각의 버튼을 누르면 아래 화면들처럼 화면이 바뀌게 됩니다. 

 


참고 : do it android 앱 프로그래밍, developer.android.com/?hl=ko 

 

Android 개발자  |  Android Developers

Android 앱 개발자를 위한 공식 사이트입니다. Android SDK 도구 및 API 문서를 제공합니다.

developer.android.com