ConcatAdapterでGridLayoutManagerの列数を可変にする

ConcatAdapterGridLayoutManager を使うときに、Adapterによって列数を可変にする方法です。

例えば、以下のような画面です。

Image for post
Image for post

実装方法

実装は結構簡単にできます。

getItemViewType

まず、各Adapterでは getItemViewType を実装して他のAdapterとカブらない値を返します。一番良いのはレイアウトIDを返す方法だと思います。

GridLayoutManager.SpanSizeLookup

次に GridLayoutManager の設定です。 GridLayoutManager.SpanSizeLookup を使って動的にSpanサイズを設定することができます。

ConcatAdapter からpositionごとに viewType を取得して、SpanSizeを設定していきます。この例だと、 R.layout.item_one_column の場合は1列表示で、その他の viewType は2列で表示する設定します。

isolateViewTypes

これだけでは、期待通りの挙動にはなりません。

ConcatAdapter はデフォルトでは viewType は Adapter ごとに0からインクリメントされた値を返します。
例えば、Adapterを3つ使ってる場合、ConcatAdapter の viewType は0, 1, 2を返します。

このviewTypeを各Adapterで設定された値を返すようにするには、以下のように ConcatAdapter.Config の設定をする必要があります。

isolateViewTypes にfalseを設定することで、各Adapterで設定されたviewTypeを返してくれるようになります。

これだけで、複雑な GridLayoutManager も実装することが可能になります。

注意

isolateViewTypes の本来の用途としては、ConcatAdapter で使用されてる各AdapterでのViewHolderを共有するものになります。
詳しくは以下の記事を参照。

そのため、もし共有されて困るような場合があれば、別の方法が必要かもしれません。

Written by

Programmer / Gamer / Google Developers Expert for Android, Kotlin / @STAR_ZERO

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store