[Android/Java] BottomNavigation

doooly·2023년 12월 16일
0

Android

목록 보기
4/5
post-thumbnail

이번 포스팅에서는 Android로 BottomNavigation을 만드는 법에 대해 다루어보겠습니다 ‼️


✅ MainActivity xml

보통 BottomNavigation을 쓰는 경우, 대다수는 MainActivity에 메뉴를 두고, 그 위에 여러 프래그먼트들이 들어갈 수 있는 FrameLayout을 둡니다

메뉴 아이템이 눌릴 때마다 눌린 아이템의 id를 조회해 그에 맞는 프래그먼트를 노출시킵니다

위의 요소들을 MainActivity의 xml에 추가해주겠습니다

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/main_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/Widget.MaterialComponents.BottomNavigationView.Colored"
        app:menu="@menu/bottom_nav_menu"/>

</LinearLayout>

⚠️ 여기서 FrameLayout의 weight를 설정해주어야 bottomNavigation이 아래로 향할 수 있습니다

  • style: @style을 통해 앱 자체에 내장되어있는 스타일을 사용
  • navigation에 들어갈 menu 리소스를 만들어 app:menu 속성에 추가 관련 설정은 아래 ⬇️




✅ Menu 만들기

navigation에 들어갈 메뉴들을 만들어줘야 합니다
res에 menu 라는 폴더를 새로 만들고 bottom.navigation.xml을 새로 추가해주겠습니다
각 메뉴의 아이콘들은 drawable에 미리 추가해주었습니다

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

    <item
        android:id="@+id/navigation_wordClock"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="세계 시계" />

    <item
        android:id="@+id/navigation_alarm"
        android:icon="@android:drawable/ic_lock_idle_alarm"
        android:title="알람" />

    <item
        android:id="@+id/navigation_stopWatch"
        android:icon="@drawable/ic_notifications_black_24dp"
        android:title="스톱워치"/>

    <item
        android:id="@+id/navigation_timer"
        android:icon="@android:drawable/ic_menu_recent_history"
        android:title="타이머" />

</menu>




✅ MainActivity class

  • onCreate()에서 MainActivity를 binding 해주고, bottomNavigation 변수를 id값을 통해 가져와 설정
  • bottomNavigation에 setOnItemSelectedListener 설정
    ➡️ 버튼이 눌릴 때마다 호출되며, 눌린 아이템의 id에 맞는 프래그먼트 실행
  • transferTo(Fragment fragment) 함수 생성
    ➡️ 프래그먼트 객체를 전달해 fragmentManager가 replace할 수 있게 함
public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

		//xml binding
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
		
        //bottomNavigationView 가져오기
        BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation);
        bottomNavigationView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                if (item.getItemId() == R.id.navigation_worldClock) {
                    transferTo(new WorldClockFragment());
                    return true;
                } else if (item.getItemId() == R.id.navigation_alarm) {
                    transferTo(new AlarmFragment());
                    return true;
                }
                else if(item.getItemId() == R.id.navigation_stopWatch){
                    transferTo(new StopwatchFragment());
                    return true;
                }
                else if(item.getItemId() == R.id.navigation_timer){
                    transferTo(new TimerFragment());
                    return true;
                }
                return false;
            }
        });
    }
    
    //fragment가 눌렸을 때 해당 프래그먼트 노출시키기
    void transferTo(Fragment fragment){
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.main_content, fragment)
                .commit();
    }

}

Activity들은 activityManager에 의해 관리되는 것처럼, Fragment들도 fragmentManager에 의해 관리됩니다

🔎 Activity와 Fragment의 차이점 중 하나는 ActivityManager은 프레임워크에 존재하나, FragmentManager은 Activity에 존재하는 것이죠

아무튼 현재 코드는 액티비티에서 사용되니 바로 fragmentManager을 get해서 사용하면 되지만, fragment에서 fragmentManager을 사용할 때는 getActivity()를 통해 액티비티를 먼저 얻은 후 getFragmentManager()을 해야 합니다 ‼️




💡 transferTo()함수에 대해 더 설명하자면,
해당 코드들은 프래그먼트 매니저가 관리하는 뷰들을 교체하는 코드입니다

교체의 종류에는 add, replace, remove 가 있고
⭐️ 이 세가지는 beginTransaction()commit() 사이에서 이루어져야 합니다

함수에서 사용한 replace는 main_content 리소스에 fragment로 뷰를 교체하겠다는 의미입니다
여기서 main_content는 저희가 mainActivity의 xml에서 만든 frameLayout이며, fragment는 인자로 들어온 fragment 객체를 뜻합니다




✅ 결과

설정한대로 4개의 navigation item이 뜨고, 각 아이템을 눌렀을 때 설정한 프래그먼트가 layout에 뜨는 것을 볼 수 있습니다😊

0개의 댓글