Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
RecyclerViewとGridLayoutManager について学んだ話
Search
Shouhei Nagai
December 18, 2018
630
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
RecyclerViewとGridLayoutManager について学んだ話
potatotips #57
Shouhei Nagai
December 18, 2018
Featured
See All Featured
The Mindset for Success: Future Career Progression
greggifford
PRO
0
510
Utilizing Notion as your number one productivity tool
mfonobong
4
600
Git: the NoSQL Database
bkeepers
PRO
432
67k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
560
Designing for Performance
lara
611
70k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
250
GitHub's CSS Performance
jonrohan
1033
470k
Mobile First: as difficult as doing things right
swwweet
225
10k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
530
It's Worth the Effort
3n
188
29k
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
710
Transcript
RecyclerViewと GridLayoutManager について学んだ話 Shohei Nagai (@nagais) 2018/12/18 potatotips #57
自己紹介 • 永井翔平(@nagais) • Androidアプリ開発を初めて1年3ヶ月ほど • 株式会社アイスタイルにて@cosmeのAndroidアプリ開発に 携わっています • potatotipsには今回が初参加で、外部の勉強会で登壇するの
も今回が初です 2
今日お話ししたいこと • Viewをリサイクルしながらグリッドで表示する方法 • ViewTypeを元にグリッドの分割数とレイアウトを変更する方 法 3
ある時… 4
こんな感じの実装依頼が • タイトル1行とアイテムを複数をセッ トとして繰り返す画面 • 1行のカラムを2つとする • タイトルとなるViewはカラム2つ分の 幅を使用する 5
View View View View View View
何に困ったか • グリッドで表示する画面がアプリ内 になく、触ったことがなかった • GridLayoutManagerが使えそうだっ たが、1行のViewと2カラムの行数 が不規則なViewをセットで繰り返す 方法が不明だった 6
View View View View View View View
どうしたか • グリッド表示のさせ方 ◦ GridLayoutManagerをセットしたRecyclerViewを使用した • 表示するviewの数が不規則 ◦ ModelにViewTypeを持たせる •
1行のViewと2カラムのViewの表示 ◦ GridLayoutManagerのSpanSizeLookupを使用した 7
グリッド表示のさせ方 8
ActivityでのRecyclerViewセッティング 9 private fun initRecyclerView () { binding.recyclerView.adapter = viewModel.customAdapter
// 2カラム指定 val layoutManager = GridLayoutManager (this, 2) binding.recyclerView.layoutManager = layoutManager } 1. RecyclerViewのAdapterにCustomAdapterをセット 2. 2カラム指定したGridLayoutManagerのインスタンス作成 3. RecyclerViewのLayoutManagerにセット
表示するview数が不規則 10
悩んだこと 11 • 2カラムのデータが可変だったため、 セクション毎にデータをまとめて管理 したくなかった • 特定のIndexで1行のViewが挿入さ れるわけでなかった Index
1 List Index 0 Index 4 Index 2 Index 3 Index 5 ここが可変
動的に表示位置を変更する 方法はないだろうか… 12
そうだ! ModelにViewTypeを持たせよう! 13
ModelにViewTypeを持たせる data class ABModel(val viewType: CustomAdapter.ViewType, val name: String, val
imageUrl: String) 14 ViewType AとBで共通で使用できるModelにViewTypeを持たせ る ViewType A → 一行のView ViewType B → 二行のView enum class ViewType(val type: Int) { A(111), B(112) }
1行のViewと2カラムのViewの表示 15
Adapter側の処理 override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerViewHolder { return
when (viewType) { ViewType.A.type -> <ViewType Aのレイアウトを保持するViewHodlerを返却する> else -> <ViewType Bのレイアウトを保持するViewHolderを返却する> } } override fun getItemViewType(position: Int) = modelList[position].viewType.type override fun onBindViewHolder(holder: RecyclerViewHolder?, position: Int) { val model = modelList[position] when (model.viewType) { ViewType.A -> (holder?.binding as ALayoutBinding).viewModel.model = model ViewType.B -> (holder?.binding as BLayoutBinding).viewModel.model = model } } 16 1. 表示するpositionのModelが持つViewTypeを利用 2. ViewTypeに合わせて返却するHolderを変更 3. ViewTypeに合わせてModelをセットするLayout変更
カラム数を動的に変更する 17 GridLayoutManagerのSpanSizeLookup()を使用して、 ViewTypeに合わせてカラム数を変更する処理を追加 private fun initRecyclerView () { binding.recyclerView.adapter
= viewModel.customAdapter // 2カラム指定 val layoutManager = GridLayoutManager(this, 2) layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() { override fun getSpanSize(position: Int): Int { return when (viewModel.customAdapter.getItemViewType(position)) { CustomAdapter.ViewType.A.type -> 2 else -> 1 } } } binding.recyclerView.layoutManager = layoutManager }
おわりに • RecyclerViewとGridLayoutManagerを使用して複数の ViewTypeを想定した場合の実装方法を紹介しました • 普段使っているライブラリでも、知らないことはまだまだあるな と思いました • 今後は普段使っているライブラリの中を覗いたり、まだ知らな い使い方があるのではないかを常に考えたい
18