LoginSignup
50
43

More than 3 years have passed since last update.

【Kotlin】BottomNavigation(下タブ) + Navigationを試してみる

Last updated at Posted at 2019-06-16

はじめに

モダンなアプリでよく使われている印象のBottomNavigation。
AndroidStudioのテンプレートを使う簡単な方法もありますが、今回は勉強のために一から作ってみます。
コードはGithubに載せています。GitHub - orimomo/bottom-navigation-test
Jun-16-2019 19-23-30.gif

環境

  • macOS: 10.14.1
  • Android Studio: 3.4
  • Kotlin: 1.3.21
  • Support Library: AndroidX

手順

依存関係の設定

以下を追加します。

app/build.gradle
dependencies {
    // MaterialComponentsのBottomNavigationを使うため
    implementation "com.google.android.material:material:1.1.0-alpha06"

    // Navigationを使うため
    def nav_version = '2.0.0'
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
}

BottomNavigationの実装

まずはBottomNavigationを動くようにします。

activity_mainにBottomNavigationの要素を追加します。

activity_main.xml
<FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <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:background="?android:attr/windowBackground"
            app:menu="@menu/bottom_navigation_menu"/>
</FrameLayout>

android:backgroundの他にもapp:itemIconTintapp:itemTextColorを指定することで見た目を変えることができます。

次はapp:menuに設定しているファイルを作っていきます。
menuパッケージを追加し、その中にbottom_navigation_menuファイルを追加します。

bottom_navigation_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
            android:id="@+id/navi_smile"
            android:icon="@drawable/ic_insert_emoticon_black_24dp"
            android:title="スマイル"/>
    <item
            android:id="@+id/navi_pets"
            android:icon="@drawable/ic_pets_black_24dp"
            android:title="ペット"/>
    <item
            android:id="@+id/navi_sun"
            android:icon="@drawable/ic_wb_sunny_black_24dp"
            android:title="太陽"/>
    <item
            android:id="@+id/navi_flight"
            android:icon="@drawable/ic_airplanemode_active_black_24dp"
            android:title="飛行機"/>
</menu>

android:iconに指定するリソースは、drawableパッケージに事前にVectorAssetとして作成したものを使っています。

ここでビルドするとBottomNavigationが表示され、タブの切り替えができるようになっていると思います。
スクリーンショット 2019-06-16 18.55.40.png

Navigationの実装

BottomNavigationのボタンを押すとそれぞれに違うFragmentを表示するようにしたいと思います。
表示させるFragmentのlayoutファイルとclassファイルをそれぞれ4つ作っておきます。

fragment_1.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"
        android:background="@color/pink">

    <TextView
            android:id="@+id/textView1"
            android:text="Fragment1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Fragment1.kt
class Fragment1 : Fragment() {
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        super.onCreateView(inflater, container, savedInstanceState)
        return  inflater.inflate(R.layout.fragment_1, container, false)
    }
}

activity_mainに以下を追加します。

activity_main.xml
<fragment
    android:id="@+id/nav_host_fragment"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:name="androidx.navigation.fragment.NavHostFragment"
    app:navGraph="@navigation/navigation_graph"/>

app:navGraphに設定しているファイルを作ります。
navigationパッケージを追加し、その中にnavigation_graphファイルを追加します。

navigation_graph.xml
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/navigation_graph"
            app:startDestination="@id/navi_smile">

    <fragment android:id="@+id/navi_smile"
              android:name="com.example.bottom_navigation_test.Fragment1"
              android:label="Fragment1"/>

    <fragment android:id="@+id/navi_pets"
              android:name="com.example.bottom_navigation_test.Fragment2"
              android:label="Fragment2"/>

    <fragment android:id="@+id/navi_sun"
              android:name="com.example.bottom_navigation_test.Fragment3"
              android:label="Fragment3"/>

    <fragment android:id="@+id/navi_flight"
              android:name="com.example.bottom_navigation_test.Fragment4"
              android:label="Fragment4"/>
</navigation>

各Fragmentに設定するidは、先程bottom_navigation_menuファイルで指定したidと同じものを対応させて使う必要がある点に注意が必要です。

最後にMainActivityでBottomNavigationとNavigationを紐づけて完成です。

MainActivity.kt
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val navController = findNavController(R.id.nav_host_fragment)
        setupWithNavController(bottom_navigation, navController)
    }
}

さいごに

リップル付きのBottomNavigationが思ったよりも簡単に実装できました◎
ただ今回の実装だとタブを切り替えるとFragmentも再生成されてしまうので、次回はFragmentの状態を保持できる実装を試してみたいと思います。

参考

Bottom navigation - Material Design
Getting Started - Material Components for Android
Navigation + BottomNavigationViewでFragmentの状態を残す – Kenji Abe – Medium
BottomNavigationView と Navigationを一緒に使う - Qiita

50
43
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
43