〈kotlin〉スワイプビューを作る① TabLayoutとViewPager
Android studioでkotlinを使ってAndroidアプリ作成。
画面上部にタブを3つ用意して、
タブを押すかスワイプすることで画面遷移ができるように実装したい。
TabLayoutとViewPager2を組み合わせることで作成できる。
参考https://developer.android.com/guide/navigation/navigation-swipe-view-2?hl=ja
TabLayoutとViewPager2を配置する
xmlファイルにLinearLayoutを配置し、
その中にTabLayoutとViewPager2をこの順番で配置する。
(失敗メモ:LinearLayoutに入れ忘れてたらタブとページが被って表示してしまったし、
順番逆にしたらページの表示が上手くできなかった。)
Paletteの中のContainersからTabLayoutを配置したが、コード記述した方が早い。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.google.android.material.tabs.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" /> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout>
タブに表示する画面の作成
今回はタブ3つ、それぞれにフラグメントを作成した。
class tabFragment() : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_tab, container, false) } }
フラグメントにはそれぞれ違う内容のtextViewだけとりあえず配置してみた。
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".allFragment"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/all_text" /> </FrameLayout>
Adapterの作成
用意したfragmentを取得できるようにAdapterを作成する。
ViewPager2を使用する場合、AdapterにはFragmentStateAdapterを使用する。
FragmentStateAdapterを継承する際には
FragmentActivity オブジェクトをコンストラクタパラメータにする。
createFragment(position:Int):指定された位置のFragmentインスタンスを返す(positionはタブの左から右)
getItemCount():アダプター内のアイテムの総数を返す
class PageAdapter(fa: FragmentActivity): FragmentStateAdapter(fa){ private val tabFragment_a = tabFragmentA() private val tabFragment_b = tabFragmentB() private val tabFragment_c = tabFragmentC() override fun createFragment(position: Int): Fragment { return when (position){ 0 -> { tabFragment_a } 1 -> { tabFragment_b } else -> { tabFragment_c } } } override fun getItemCount(): Int { return 3 } }
Activityで呼び出す
配置したViewPager2にAdapterを設定し、
TabLayoutMediatorでTabLayoutとViewPager2をリンクさせる。
このとき同時にTabLayoutオブジェクトのページタイトルを生成するタスクも実行される。
class MainActivity : AppCompatActivity() { private lateinit var viewPager: ViewPager2 override fun onCreate(savedInstanceState: Bundle?) { // viewPager = findViewById(R.id.pager) val pagerAdapter = PageAdapter(this) viewPager.adapter = pagerAdapter val tabLayout = view.findViewById(R.id.tab_layout) TabLayoutMediator(tabLayout, viewPager) { tab, position -> tab.text = "TAB ${(position + 1)}" }.attach() } }