Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
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
160
CameraX使ってみた
takuji31
0
310
kotlinx.datetime 使ってみた
takuji31
0
1.1k
HiltのCustom Componentについて
takuji31
0
380
java.timeをAndroidで使う
takuji31
0
200
KSPを使ってコード生成
takuji31
0
480
Kotlin Symbol Processing API (KSP) を使って Kotlin ア プリケーションの開発を効率化する
takuji31
1
3.2k
kotlinx.serialization
takuji31
0
700
kanmoba-returns-02.pdf
takuji31
0
300
Other Decks in Technology
See All in Technology
AI Coding Agent時代のcdk-nagガードレール 〜組織ルールを強制CIで守り抜く設計の挑戦〜
mhrtech
3
420
SRE本の知られざる名シーン / The Hidden Gems of Google SRE Book
nari_ex
1
420
しぶいSRE: サーバから見えない障害にどう向き合うか。ラストワンマイルのデバッグ実践 / Shibui SRE
kanny
13
6.5k
ガバナンスの「ちょうどいい落とし所」を探れ!開発スピードを妨げない運用判断の勘所 / SRE NEXT 2026
genda
1
250
生成AI×AWS CDK×AWS FISで"振り返れる"ミニGameDayをつくろう
yoshimi0227
1
410
非定型なドキュメントを効率よくリファクタする 〜えぇ!?仕様書27本の移行が1日で終わったって!?〜
subroh0508
2
560
AI時代のPlaywright活用(システムテストを自動化する ー 実行エンジンにPla ywrightを選んだ理由)
ynisqa1988
1
450
AI、CDK と協働する Full TypeScript アプリケーション開発 / Full TypeScript Application with AI and CDK
geekplus_tech
2
400
SRE依存からの脱却 運用を開 発チームへ移す、 フルサイ クル開 発体制の実践
joooee0000
0
3.2k
AI時代のYAGNI:「爆速で無駄になった機能」からの学び / 20260720 Naoki Takahashi
shift_evolve
PRO
2
320
Amplify Gen2でbackend.tsにCDKを定義する/しない事によるCDKの挙動の違いとユースケース
smt7174
1
420
脱金融のフューチャー・デザイン / Future Design Beyond Finance
ks91
PRO
0
160
Featured
See All Featured
Typedesign – Prime Four
hannesfritz
42
3.1k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
730
How GitHub (no longer) Works
holman
316
150k
A better future with KSS
kneath
240
18k
It's Worth the Effort
3n
188
29k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
190
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
180
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.9k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
A Soul's Torment
seathinner
6
3.1k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.1k
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/