[Android/Kotlin] 커스텀 BottomNavigation 만들기

코코아의 개발일지·2023년 8월 6일
0

Android-Kotlin

목록 보기
7/31
post-thumbnail

✍🏻 요구사항 분석

해커톤에서 아래와 같이 클릭할 때마다 배경이 노란색이 되는 바텀네비를 만들어주어야 했다.



💻 구현 코드

1. 이미지 넣어주기

아래처럼 선택했을 때와 선택하지 않았을 때의 아이템 이미지를 각각 넣어준다. 아이템 개수만큼 넣어주면 된다.

2. drawable에 selector를 만들어준다.

1에서 추가한 선택했을 때와 아닐 때의 이미지를 각각 넣어주고, state_checked를 설정해준다. 얘도 아이템 개수만큼 만들어주면 된다.

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_btn_record_selected" android:state_checked="true"/>
    <item android:drawable="@drawable/ic_btn_record_unselected" android:state_checked="false"/>
</selector>




3. menu 구성

앞서 2에서 만든 selector를 각 아이템에 집어넣어준다.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/main_bottom_nav_home"
        android:icon="@drawable/selector_nav_home"
        android:title="" />

    <item
        android:id="@+id/main_bottom_nav_record"
        android:icon="@drawable/selector_nav_record"
        android:title="기록" />

    <item
        android:id="@+id/main_bottom_nav_friends"
        android:icon="@drawable/selector_nav_friends"
        android:title="친구 목록" />
</menu>




4. 바텀네비 배경에 넣어줄 둥근 drawable 파일을 만들어준다.

  • 양쪽 상단 모서리는 둥글게
  • 테두리는 검정색으로
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <solid android:color="@color/white" />
    <stroke
        android:width="1dp"
        android:color="@color/black"/>
    <corners
        android:topLeftRadius="25dp"
        android:topRightRadius="25dp"/>
</shape>




5. activity_main.xml 파일에 바텀네비게이션을 넣어준다.

  • 앞서 4에서 만든 파일을 background로, 3에서 만든 menu를 menu로 추가한다.
  • itemBackgrounditemRippleColor 투명하게 설정해준다.
<?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=".presentation.ui.main.view.MainActivity">

    <FrameLayout
        android:id="@+id/main_layout_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/main_layout_bottom_navigation" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/main_layout_bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        android:background="@drawable/bg_bottom_nav"
        app:itemBackground="@android:color/transparent"
        app:itemRippleColor="@android:color/transparent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:labelVisibilityMode="unlabeled"
        app:itemIconSize="50dp"
        app:menu="@menu/main_bottom_nav" />

</androidx.constraintlayout.widget.ConstraintLayout>




6. MainActivity에서 화면 이동 설정

마지막 단계이다. MainActivity에서 바텀네비 아이템을 클릭했을 때의 이동할 프래그먼트를 설정해준다.
showInit()은 최초에 보여줄 프래그먼트를, initBottomNav()는 바텀네비 아이템을 선택했을 때의 동작을 지정한 함수이다.

class MainActivity : AppCompatActivity() {
    private lateinit var binding : ActivityMainBinding
    val manager = supportFragmentManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        showInit()
        initBottomNav()
    }

    private fun initBottomNav() {
        binding.mainLayoutBottomNavigation.itemIconTintList = null

        binding.mainLayoutBottomNavigation.setOnItemSelectedListener {
            when(it.itemId) {
                R.id.main_bottom_nav_home -> {
                    HomeFragment().changeFragment()
                }

                R.id.main_bottom_nav_friends -> {
                    FriendsFragment().changeFragment()
                }

                R.id.main_bottom_nav_record -> {
                    RecordFragment().changeFragment()
                }
            }
            return@setOnItemSelectedListener true
        }

        binding.mainLayoutBottomNavigation.setOnItemReselectedListener {  } // 바텀네비 재클릭시 화면 재생성 방지
    }

    private fun Fragment.changeFragment() {
        manager.beginTransaction().replace(R.id.main_layout_container, this).commit()
    }

    fun showInit() {
        val transaction = manager.beginTransaction()
            .add(R.id.main_layout_container, HomeFragment())
        transaction.commit()
    }
}



🤩 구현 결과

gif 변환한 거라.. 화질이 좀 깨지긴 하지만 잘 나오는 모습을 확인할 수 있다!



📚 참고

깃허브: https://github.com/Neordinary-Hack/neo_Android.git

profile
우당탕탕 성장하는 개발자

0개의 댓글