【正社員】還元率83%【フリーランス】マージン一律5万円で案件をご紹介させていただきます。 詳細はこちら

【Android】Kotlinでアプリ画面にタブを作ろう!TabLayoutとViewPager2を使って横スワイプ可能なタブの実装を徹底解説

【Android】Kotlinでアプリ画面にタブを作ろう!TabLayoutとViewPager2を使って横スワイプ可能なタブの実装を徹底解説
すだ

みなさまこんにちは〜!
メモリアインクのすだです。

本日は、
KotlinでAndroidアプリ画面にタブを実装する方法を、
実際のコードを用いてわかりやすく解説していきます!

この記事を読んでわかること…
・TabLayoutとViewPager2の使い方について
・タブ画面の実装手順

目次

環境

  • Kotlin (ver 1.9.0)
  • Android Studio (Giraffe | 2022.3.1 Patch 3)

TabLayoutとViewPager2とは?

TabLayout

TabLayoutは、画面上部に「タブ(カテゴリーや項目の切り替えを行う部分)」を表示するためのUIコンポーネントです。タブをクリックすると、対応するコンテンツが切り替わります。

ViewPager2

ViewPager2は、画面をスワイプしてコンテンツを切り替える仕組みを提供するコンポーネントです。
タブと連携させることで、横スワイプによる切り替えが可能になります。

横スワイプ可能なタブの概要と仕組み

TabLayoutViewPager2を組み合わせると、以下のような操作が可能になります▼

  • タブをタップして画面を切り替える
    TabLayoutがタブの操作を管理します。
  • 横スワイプで画面を切り替える
    ViewPager2がスワイプの操作を管理します。

この連携は、TabLayoutMediator(タブとスワイプの動作をつなぐクラス)によって実現します。

【Android】Kotlinでアプリ画面にタブを作ろう!TabLayoutとViewPager2を使って横スワイプ可能なタブの実装を徹底解説

TabLayoutとViewPager2を使ったタブ画面の実装手順

1. 必要な準備

プロジェクトのbuild.gradleに以下の依存関係を追加します。

implementation 'com.google.android.material:material:1.9.0'
implementation 'androidx.viewpager2:viewpager2:1.0.0'

1行目
「Googleの Designコンポーネント」を利用するためのライブラリです。
TabLayoutを含む多くのコンポーネント(ボタン、ダイアログ、スナックバーなど)が利用可能になります

2行目
ViewPager2を使用するためのライブラリです。

2. レイアウトの作成

以下のようなレイアウトを作成します。TabLayoutViewPager2を使った基本構造です。

res/layout/activity_main.xml

<androidx.coordinatorlayout.widget.CoordinatorLayout
    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">

    <!-- ポイント① TabLayout (タブ表示部分) -->
    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="fixed"
        app:tabGravity="fill" />

    <!-- ポイント② ViewPager2 (スワイプで切り替える部分) -->
    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

上記レイアウトは、以下の2つの主要なUIコンポーネントを含んでいます:

<!--ポイント① TabLayout (タブ表示部分)-->

TabLayout
画面上部にタブ(ボタンのようなもの)を表示し、タブをタップすると対応する画面を表示します。
タブが水平に並びます。


<!--ポイント② ViewPager2 (スワイプで切り替える部分)-->

ViewPager2
画面のスワイプ操作を検知し、スワイプで画面(タブ)を切り替えます。
TabLayoutと連携させることで、スワイプ操作でタブも切り替わるようになります。

これらをCoordinatorLayoutで囲って、レイアウトの動作を調整しています。

また、タブそれぞれの画面に対応するレイアウトファイルも用意してください。

res/layout/fragment_tab1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textTab1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="タブ1の画面"
        android:textSize="24sp"
        android:textColor="#000000"
        android:textStyle="bold" />
</LinearLayout>

res/layout/fragment_tab2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textTab1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="タブ1の画面"
        android:textSize="24sp"
        android:textColor="#000000"
        android:textStyle="bold" />
</LinearLayout>

3. Fragmentの作成

各タブで表示する内容をFragmentとして作成します。

Tab1Fragment.kt ▼

class Tab1Fragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        val view = inflater.inflate(R.layout.fragment_tab1, container, false)
        return view
    }
}

Tab2Fragment.kt ▼

class Tab2Fragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        val view = inflater.inflate(R.layout.fragment_tab2, container, false)
        return view
    }
}

4. ViewPager2用のAdapter作成

ViewPager2でタブの切り替えを管理するためのAdapterを作成します。

class TabsPagerAdapter(activity: FragmentActivity) : FragmentStateAdapter(activity) {
    override fun getItemCount(): Int = 2 // タブの数

    override fun createFragment(position: Int): Fragment {
        return when (position) {
            0 -> Tab1Fragment()
            1 -> Tab2Fragment()
            else -> throw IllegalArgumentException("エラー")
        }
    }
}

このあと、上記TabsPagerAdapterViewPager2にセットしますが
そうすることによってタブと画面の切り替えが連携します。

また、createFragmentメソッドでタブの位置に応じたFragmentを動的に作成します。

5. TabLayoutとViewPager2の連携

最後に、TabLayoutMediatorを使用して TabLayoutViewPager2を連携させます。

MainActivity.kt

class MainActivity : AppCompatActivity() {
    // ポイント①
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // ポイント②
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // ポイント③ 
        val adapter = TabsPagerAdapter(this)
        binding.viewPager.adapter = adapter

        // ポイント④
        TabLayoutMediator(binding.tabLayout, binding.viewPager) { tab, position ->
            tab.text = when (position) {
                0 -> "Tab 1" // 最初のタブ
                1 -> "Tab 2" // 2番目のタブ
                else -> null
            }
        }.attach()
    }
}

// ポイント①
ActivityMainBinding
activity_main.xml に対応するバインディングクラス。
これにより、findViewByIdを使わずにUIコンポーネント(例: tabLayout, viewPager)に直接アクセスできます。


// ポイント②
binding = ActivityMainBinding.inflate(layoutInflater)
activity_main.xml のレイアウトをメモリに読み込み、対応するビューを操作可能にします。
setContentView(binding.root)

バインディングオブジェクトのルートビュー(binding.root)を画面に表示します。


// ポイント③
binding.viewPager.adapter = adapter
ここで、ViewPager2にAdapterをセットします。


// ポイント④
TabLayoutMediator

スワイプで画面が切り替わったときに、対応するタブの選択状態が更新されます。
、タブに表示するテキストを設定します。


それでは、さっそくビルドしてみましょ〜!

【Android】Kotlinでアプリ画面にタブを作ろう!TabLayoutとViewPager2を使って横スワイプ可能なタブの実装を徹底解説


タブが表示されて、横へスライドさせるとタブと画面が切り替わる画面が完成しました!

ここで注意!

View Bindingは、レイアウトファイル名から対応するバインディングクラスを自動生成します。
そのため、以下のルールに基づいて一致させる必要がありますのでご注意を!↓

レイアウトファイル名 → 自動生成されるバインディングクラス名
レイアウトファイル名がactivity_main.xmlの場合 → ActivityMainBindingというクラスが生成される
レイアウトファイル名がfragment_home.xmlの場合 → FragmentHomeBindingというクラスが生成される

このように、View Bindingではファイル名 + Bindingという命名規則が厳密に適用されるため、ActivityMainBindingを使用するには、レイアウトファイルがactivity_main.xmlでなければ動きません。

まとめ

おつかれさまでした!いかがでしたでしょうか!

タブを増やして、複数画面にスムーズにできるよう、
お好きにカスタマイズしてみてください!

すだ

技術者としてのキャリアパスを次のレベルへと進めたい皆様、
未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】
を通じて、
自分の市場価値をさらに向上させてみませんか?

それではまた次の記事でお会いしましょう!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

弊社テックブログをご愛読いただきありがとうございます。
当テックブログを運用している株式会社メモリアインクは、
【正社員】還元率83%
【フリーランス】マージン一律5万円で案件のご紹介
と、エンジニアの皆様に分かりやすい形で稼げる仕組みを構築し提供させていただいております。詳しくは弊社お問い合わせページ、プロフィールのQRコードを読み取り、LINEメッセージでお問い合わせいただけますと幸いです。

コメント

コメントする

目次