概要
力をつけるために家計簿アプリの作成に挑戦しています!
今回はBottomNavigationViewの実装について紹介したいと思います。
実装内容
以下のように、ナビゲーションの選択でfrgamentを切り替える実装をしました。
実装方法
BottomNavigationViewで検索すると色々な実装方法が検索結果で出てきます。
私が採用した方法は
ViewPager2
とFragmentStateAdapter
を使用する方法です。
以下、コードです。
xmlファイル
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/main_contents"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/bottom_navigation"
app:layout_constraintStart_toStartOf="parent"/>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:elevation="0dp"
android:background="?android:attr/windowBackground"
app:menu="@menu/bottom_navigation_menu"
app:layout_constraintTop_toBottomOf="@id/main_contents"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
レイアウトファイルを作成します。
Adapter
class BaseFragmentAdapter<T>(
itemsSource: MutableList<T>,
fragmentManager: FragmentManager?,
lifecycle: Lifecycle?
) : FragmentStateAdapter(
fragmentManager!!, lifecycle!!
) {
private var itemsSource: List<T> = itemsSource
override fun createFragment(position: Int): Fragment {
return (itemsSource[position] as BaseFragmentModel).fragment
}
override fun getItemCount(): Int {
return itemsSource.size
}
}
FragmentStateAdapterを拡張したAdapterクラスを作成します。
Activity
class ContentsActivity : AppCompatActivity(){
:
:
//Fragmentのモデルを使用したリストを作成(後ほどこのリストにFragmentを追加していく)
private val fragmentList = mutableListOf<BaseFragmentModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_contents)
val viewPager = findViewById<ViewPager2>(R.id.main_contents)
val navigation = findViewById<BottomNavigationView>(R.id.bottom_navigation)
//Fragmentを追加
addFragment()
:
:
//Adapterをセットする
viewPager.adapter = BaseFragmentAdapter(fragmentList,supportFragmentManager,lifecycle)
//ナビゲーションで選択中のアイテムを指定
viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
navigation.menu.getItem(position).isChecked = true
}
})
navigation.setOnItemSelectedListener(this::navigationItemSelected)
:
:
}
private fun addFragment() {
fragmentList.add(
BaseFragmentModel(
InputFragment()
)
)
fragmentList.add(
BaseFragmentModel(
CalendarFragment()
)
)
fragmentList.add(
BaseFragmentModel(
ReportFragment()
)
)
fragmentList.add(
BaseFragmentModel(
SettingFragment()
)
)
}
private fun navigationItemSelected(item: MenuItem): Boolean {
val viewPager = findViewById<ViewPager2>(R.id.main_contents)
viewPager.adapter = BaseFragmentAdapter(fragmentList, supportFragmentManager,lifecycle)
when (item.itemId) {
R.id.navi_input -> {
viewPager.setCurrentItem(0, false)
}
R.id.navi_calendar -> {
viewPager.setCurrentItem(1, false)
}
R.id.navi_report -> {
viewPager.setCurrentItem(2, false)
}
R.id.navi_setting -> {
viewPager.setCurrentItem(3, false)
}
else -> return false
}
return true
}
}
Adapterのセット、Fragmentの追加、bottomNavigationの設定を実装します。
最後に
bottomNavigationViewについて完全に理解できている訳ではありませんが、それなりに実装してみました!
理解に誤りや補足事項があればコメントしていただけるととても嬉しいです!