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
No more Adapter with Epoxy and Data Binding
Search
Takuji Nishibayashi
March 01, 2019
Technology
1.1k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
No more Adapter with Epoxy and Data Binding
Takuji Nishibayashi
March 01, 2019
More Decks by Takuji Nishibayashi
See All by Takuji Nishibayashi
compose-hot-reload を試そうとした話
takuji31
0
180
CameraX使ってみた
takuji31
0
340
kotlinx.datetime 使ってみた
takuji31
0
1.2k
HiltのCustom Componentについて
takuji31
0
460
java.timeをAndroidで使う
takuji31
0
220
KSPを使ってコード生成
takuji31
0
510
Kotlin Symbol Processing API (KSP) を使って Kotlin ア プリケーションの開発を効率化する
takuji31
1
3.3k
kotlinx.serialization
takuji31
0
720
kanmoba-returns-02.pdf
takuji31
0
320
Other Decks in Technology
See All in Technology
In-Context Learning再入門。ICLの勾配降下的解釈の研究動向を追ってみる。
dai08srhg
1
200
OneLakeをデータソースにした AI Search(Foundry IQ)の ライフサイクル管理
ryuseiiida
0
220
試験勉強はGrokBotでやれ
maigo999
0
110
推論基盤と Scale-Up Interconnect の現状と制約から俯瞰する技術動向
markunet
2
800
Microsoft Entra Kerberos で実現するクラウド デバイス管理
tamaiyutaro
0
120
AI Agent 時代のデータ基盤: ClickHouse で実現する 超高速分析とコスト削減の両立
jozono
0
130
"AWSはちょっと苦手"でも大丈夫。AWS Blocks で手軽に作る Flutter のバックエンド #FlutterKaigi
tacck
PRO
0
140
PostgreSQL オプティマイザ統計の秘密
nori_shinoda
0
310
バックオフィスに染み出すTypeScript ── clasp で安全に仕組みを作る
nealle
1
180
SLOを阻む不安
sraku2159
0
220
スマートロックを支えるFlutter × ネイティブ連携の実践 / Flutter and Native Integration in Practice: Powering Smart Locks
bitkey
PRO
0
150
re:Invent の去年のスケジュールを公開します!
miu_crescent
PRO
0
270
Featured
See All Featured
A Soul's Torment
seathinner
8
3.9k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
540
Visualization
eitanlees
153
17k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
360
How to make the Groovebox
asonas
2
2.5k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
420
Building Adaptive Systems
keathley
44
3.3k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
So, you think you're a good person
axbom
PRO
2
2.2k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
3
3.9k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
620
Amusing Abliteration
ianozsvald
1
380
Transcript
No more Adapter with Epoxy and Data Binding @takuji31 ژDev͔;͐
#5
ࣗݾհ
ࣗݾհ • @takuji31 id:takuji31 • Takuji Nishibayashi • Hatena Co.,
Ltd. • App Team • δϟϯϓϧʔΩʔʂ • ίϛοΫDAYS • ΧΫϤϜ
ࣗݾհ • Android • Kotlin • ! https://blog.takuji31.jp • "
https://nazuna.takuji31.jp • # $ https://photo.takuji31.jp
RecyclerView
ͬͯͳ͍ਓ͍·ͤΜΑͶʁ
ViewHolder + Adapter
ΦϓγϣϯͰ DiffUtil
blog.takuji31.jp/entry/kanmoba17
ෳࡶͳը໘
None
Ͳ͏࣮ݱ͢Δʁ
खͰؤுΔ
ViewHolderΛview type͝ͱʹ࡞Δ
onCreateViewHolderͰ֘͢Δ ViewHolderΛ࡞Δ
onBindViewHolderͰViewHolderͷ ܕΛݟͯΛઃఆ
มߋݕ
DiffUtilͰؤுΔ
!
Section Library
※ ͍͔ͭ͘ϥΠϒϥϦʔ͕͋Γ·͢ ͕ҰൠతͳͰ͢
view typeͷΘΓʹSectionͱ͍͏ ΫϥεΛ͏
Section class WorkSection(val items:List<Work>): Section<WorkViewHolder>() { override fun onCreateViewHolder(inflator: LayoutInflator,
parent: ViewGroup): WorkViewHolder { return WorkViewHolder(inflator.inflate(R.layout.recycle_item_work, parent, false)) } override fun onBindViewHolder(viewHolder: WorkViewHolder, position: Int) { val work = items[position] viewHolder.title = work.title Picasso.get().load(work.imageUri).into(viewHolder.imageView) } }
Adapter val adapter = Adapter() adapter.addSection(BannerSection(works)) adapter.addSection(WorkSection(works.take(10))) adapter.addSection(EntrySection(works)) adapter.addSection(WorkSection(works.drop(10)))
ύοͱݟ؆୯ͦ͏
ΫϦοΫΠϕϯτͷୡͲ͏͢Δ…ʁ class WorkSection(val items:List<Work>, val onClick: (Work) -> Unit): Section<WorkViewHolder>()
{ override fun onCreateViewHolder(inflator: LayoutInflator, parent: ViewGroup): WorkViewHolder { return WorkViewHolder(inflator.inflate(R.layout.recycle_item_work, parent, false)) } override fun onBindViewHolder(viewHolder: WorkViewHolder, position: Int) { val work = items[position] viewHolder.title = work.title Picasso.get().load(work.imageUri).into(viewHolder.imageView) viewHolder.itemView.setOnClickListener { onClick() } } }
Adapter val adapter = Adapter( {work -> viewModel.onWorkSelected(work)}, {entry ->
viewModel.onEntrySelected(entry)}, {banner -> viewModel.onBannerSelected(banner)}, ) adapter.addSection(BannerSection(works)) adapter.addSection(WorkSection(works.take(10))) adapter.addSection(EntrySection(works)) adapter.addSection(WorkSection(works.drop(10)))
ͪΐͬͱ໘
ͦͦ
Adapter -> Section -> ViewHolder
֊͕૿͑Δ
ঢ়ଶΛόϥόϥʹ͍࣋ͬͯͨΓ͢Δ ͱ෮ݩͰࢮ͵
Ϋϥε૿͑Δ
ॳݟͰΊͬͪΌΉ͍ͣ
Epoxy
github.com/airbnb/epoxy
No more
ViewHolder
notifyDataSetChanged()
Adapter
Carousel support
Data Binding Friendly
Kotlin DSL support!!!
build.gradle dependencies { implementation "com.airbnb.android:epoxy:3.3.0" implementation "com.airbnb.android:epoxy-databinding:3.3.0" kapt "com.airbnb.android:epoxy-processor:3.3.0" }
package-info.java @EpoxyDataBindingPattern(rClass = R.class, layoutPrefix = "recycler") package jp.takuji31.epoxyexample; import
com.airbnb.epoxy.EpoxyDataBindingPattern;
recycler_item_work.xml <layout> <data> <variable name="work" type="jp.takuji31.epoxyexample.model.Work" /> <variable name="onClick" type="android.view.View.OnClickListener"
/> </data> <androidx.cardview.widget.CardView android:onClick="@{onClick}"> <androidx.constraintlayout.widget.ConstraintLayout> <ImageView app:imageUri="@{work.imageUri}"/> <TextView android:text="@{work.title}"/> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.cardview.widget.CardView> </layout>
Activity or Fragment recyclerView.withModels { works.forEach { work -> itemWork
{ id("work_${work.id}") work(work) } } }
None
!
Carousel
Carousel recyclerView.withModels { carousel { id("entryCaroucel") withModelsFrom(entries) { entry ->
ItemEntryBindingModel_() .id("entry_${entry.id}") .entry(entry) } } }
None
؆୯͗͢Ͱ
ෳࡶͳϨΠΞτ
ෳࡶͳϨΠΞτ Carousel.setDefaultGlobalSnapHelperFactory(null) carousel { id("bannerCarousel") withModelsFrom(banners) { ItemBannerBindingModel_() .id("banner_${it.id}") .banner(it)
} } works.take(10).forEach { work -> itemWork { id("work_${work.id}") work(work) } }
ෳࡶͳϨΠΞτ headerBlogEntry { id("blog_header") } carousel { id("entryCaroucel") withModelsFrom(entries) {
entry -> ItemEntryBindingModel_() .id("entry_${entry.id}") .entry(entry) } } works.drop(10).forEach { work -> itemWork { id("work_${work.id}") work(work) } }
ʂ
https://github.com/takuji31/epoxy- example
Enjoy RecyclerView life
! ࠾༻ใ
גࣜձࣾͯͳͰɺ ͱʹʮઓʯͰ͖Δ ؒΛืू͍ͯ͠·͢
͜ΜͳਓΛ୳͍ͯ͠·͢ • AndroidΞϓϦΛ࡞Γ͍ͨਓ • iOSΞϓϦΛ࡞Γ͍ͨਓ • ͋Δ͍྆ํ • ͳΜͳΒαʔόʔαΠυ
https://hatenacorp.jp/recruit/