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
今更ながらEpoxy / Lateinit Epoxy
Search
Sho Masegi
November 06, 2018
Technology
900
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
今更ながらEpoxy / Lateinit Epoxy
今更ながらEpoxyを触ってみました。
Sho Masegi
November 06, 2018
More Decks by Sho Masegi
See All by Sho Masegi
独自の共通認証基盤を用いているサービスでアカウント削除機能を提供したときの道程
shomasegi
1
3.3k
Migrate Swift 4.2 to 5.2
shomasegi
4
900
Material Components ことはじめ / Get Started Material Components
shomasegi
0
820
Other Decks in Technology
See All in Technology
Slack上でインフラをトラブルシュートする! Agentic Platform Engineeringの第一歩
teru0x1
5
1.8k
AIエージェントの自己改善をどう設計するか / How to Design Self-Improvement for AI Agents
22mi
25
17k
登壇の自信を奪う3匹のオバケ / 3 Ghosts That Rob You of Your Confidence in Public Speaking
pauli
9
1.1k
Azure Serverless 2026:Production-ready な AI エージェント基盤 / Azure Serverless 2026: Production-Ready AI Agent Platform
miyake
2
490
白金鉱業Meetup Vol.25 アウトカムが二値のデータに対するCausal Impact
brainpadpr
0
270
ソフトウェアDNAとクラウドエージェントのススメ
cloudace
0
120
あけおめLINE 傾向とその対策
nasa9084
0
210
Issue 駆動でスペシャリストの意図を届ける、AI 実装のアクセシビリティ向上
thkt
0
130
人間はどの意思決定を手放せるのか
kawasima
15
7.9k
[Kiro Meetup #7] Kiro Crew Dive Deep
konippi
0
120
AIに任せた品質は、誰が見立てるのか - AI時代のテストマネジメント
nakanao
3
2.7k
CLIライブラリ開発を支える技術
htnabe
0
140
Featured
See All Featured
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
540
How STYLIGHT went responsive
nonsquared
100
6.3k
Designing Powerful Visuals for Engaging Learning
tmiket
1
570
How to Ace a Technical Interview
jacobian
281
24k
WENDY [Excerpt]
tessaabrams
14
39k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
290
Discover your Explorer Soul
emna__ayadi
2
1.3k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
770
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
390
Into the Great Unknown - MozCon
thekraken
41
2.7k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
900
The agentic SEO stack - context over prompts
schlessera
0
940
Transcript
ࠓߋͳ͕ΒEpoxy ɹ Sho Masegi
ࣗݾհ • όέπඃͬͯ·͢ɻ • େֶੜͰ͢ɻ • Androidɺ࣌ʑiOS • ࠷ۙ iOS
> Android @boc_sho
ͬͨ͜ͱ͋Δํ͍·͔͢ʁ
ກձΛଓ͚͍ͯͩ͘͞
ࠓճ͢͜ͱ • Epoxyͱʁ • Epoxyͷ؆୯ͳ͍ํ
͞ͳ͍͜ͱ • Epoxyͷ࣮ફతͳ͍ํ • ଞͷϥΠϒϥϦͱൺͯͲ͏͔
͜ͷϨΠΞτͲ͏ͬͯΉ?
͜ͷϨΠΞτͲ͏ͬͯΉ?
RecyclerView or ScrollView ?
ͪΐͬͱ໘ͦ͘͞͏…
ෳࡶͳϨΠΞτΛ ؆୯ʹΈ͍ͨʂ
ͦ͜Ͱ Epoxy !!
Epoxyͱ?
Epoxyͱ? • ෳࡶͳը໘ΛRecyclerViewͰ࡞ΔͨΊͷϥΠϒϥϦ • Airbnb͕࡞͍ͯ͠Δ • 2016/08/25 Initial public release
• ࠓͰ݁ߏ׆ಈ͍ͯ͠Δ
Ͳ͏͍͏͜ͱ͕Ͱ͖Δͷʁ
Epoxyͱ? • ҧ͏ϨΠΞτͷCellΛRecyclerViewͰ؆୯ʹදࣔ Ͱ͖Δ • ಈతʹCellΛೖΕସ͑ͨΓͰ͖Δ
Epoxyͱ? .kt .xml or Epoxy EpoxyModel ϨΠΞτϑΝΠϧ͔ΒEpoxyModelΛ ࣗಈੜ
override fun buildModels(city: City) { headerView { id(“header view”) cityName(city.name)
description(city.description) } linkView { id(“link view”) onClick { _ -> callbacks.onLinkClick() } } carouselHeaderView { id(“carousel header view”) onClick { _ -> callbacks.onSeeAllClick() } } carouselView { id(“carousel view”) EpoxyModel EpoxyModel EpoxyModel EpoxyRecyclerView Epoxyͱ?
͜ͷϨΠΞτΛEpoxyͰΉͱ….
override fun buildModels(city: City) { headerView { id(“header view”) cityName(city.name)
description(city.description) } linkView { id(“link view”) onClick { _ -> callbacks.onLinkClick() } } // . . . . EpoxyͰΉͱ….
override fun buildModels(city: City) { headerView { id(“header view”) cityName(city.name)
description(city.description) } linkView { id(“link view”) onClick { _ -> callbacks.onLinkClick() } } // . . . . EpoxyͰΉͱ….
override fun buildModels(city: City) { headerView { id(“header view”) cityName(city.name)
description(city.description) } linkView { id(“link view”) onClick { _ -> callbacks.onLinkClick() } } // . . . . EpoxyͰΉͱ….
override fun buildModels(city: City) { // . . . .
carouselHeaderView { id(“carousel header view”) onClick { _ -> callbacks.onSeeAllClick() } } carouselView { id(“carousel view”) homes(city.homes) onClick { _ -> callbacks.onHomeClick() } } footerView { . . . . } EpoxyͰΉͱ….
override fun buildModels(city: City) { // . . . .
carouselHeaderView { id(“carousel header view”) onClick { _ -> callbacks.onSeeAllClick() } } carouselView { id(“carousel view”) homes(city.homes) onClick { _ -> callbacks.onHomeClick() } } footerView { . . . . } EpoxyͰΉͱ….
override fun buildModels(city: City) { // . . . .
carouselHeaderView { id(“carousel header view”) onClick { _ -> callbacks.onSeeAllClick() } } carouselView { id(“carousel view”) homes(city.homes) onClick { _ -> callbacks.onHomeClick() } } footerView { . . . . } EpoxyͰΉͱ….
override fun buildModels(city: City) { // . . . .
carouselHeaderView { id(“carousel header view”) onClick { _ -> callbacks.onSeeAllClick() } } carouselView { id(“carousel view”) homes(city.homes) onClick { _ -> callbacks.onHomeClick() } } footerView { . . . . } EpoxyͰΉͱ….
؆୯ͦ͏͡ΌΜ
ಋೖͯ͠ΈΑ͏ʂ
1. ४උ 2. EpoxyModel (CellView)Λ࡞ 3. Controller (Adapter)Λ࡞ 4. EpoxyRecyclerViewΛFragmentʹՃ͢Δ
खॱ
1. ४උ
apply plugin: ‘kotlin-kapt’ kapt { correctErrorTypes = true // .
. . } build.gradle ͍ͭͷ
dependencies { // . . . implementation ‘com.airbnb.android:epoxy:2.x.y’ implementation ‘com.airbnb.android:epoxy-databinding:2.x.y’
kapt ‘com.airbnb.android:epoxy-processor:2.x.y’ // . . . } build.gradle ͍ͭͷ
͜Ε package-info.java ͍ͭͷ͡Όͳ͍ͭ
package-info.javaͱʁ • DataBindingΛͬͯEpoxyModelΛ࡞Δͷʹඞཁ
• DataBindingΛͬͯEpoxyModelΛ࡞Δͷʹඞཁ package-info.javaͱʁ override fun buildModels(city: City) { headerView {
id(“header view”) cityName(city.name) description(city.description) } linkView { id(“link view”) onClick { _ -> callbacks.onLinkClick() } } EpoxyModel EpoxyModel
• DataBindingΛͬͯEpoxyModelΛ࡞Δͷʹඞཁ • ͲͷϨΠΞτϑΝΠϧ͔ΒEpoxyModelΛ࡞Δ͔ɺ ͱ͍͏Indexͷׂ • ಛघͳJavaϑΝΠϧ package-info.javaͱʁ
package-info.javaͱʁ @EpoxyDataBindnigPattern(rClass = R.class, layoutPrefix = “epoxy_layout”) @EpoxyDataBindingLayouts({R.layout.header_view, . .
.}) package com.tutorial.epoxy; import com.airbnb.epoxy.EpoxyDataBindingPattern; import com.airbnb.epoxy.EpoxyDataBindingLayouts; package-info.java
package-info.javaͱʁ @EpoxyDataBindnigPattern(rClass = R.class, layoutPrefix = “epoxy_layout”) @EpoxyDataBindingLayouts({R.layout.header_view, . .
.}) package com.tutorial.epoxy; import com.airbnb.epoxy.EpoxyDataBindingPattern; import com.airbnb.epoxy.EpoxyDataBindingLayouts; package-info.java
@EpoxyDataBindingPattern (಄ޠ) @EpoxyDataBindnigPattern(rClass = R.class, layoutPrefix = “epoxy_layout”) epoxy_layout_header.xml Epoxy
HeaderBindingModel_.java
package-info.javaͱʁ @EpoxyDataBindnigPattern(rClass = R.class, layoutPrefix = “epoxy_layout”) @EpoxyDataBindingLayouts({R.layout.header_view, . .
.}) package com.tutorial.epoxy; import com.airbnb.epoxy.EpoxyDataBindingPattern; import com.airbnb.epoxy.EpoxyDataBindingLayouts; package-info.java
package-info.javaͱʁ @EpoxyDataBindnigPattern(rClass = R.class, layoutPrefix = “epoxy_layout”) @EpoxyDataBindingLayouts({R.layout.header_view, . .
.}) package com.tutorial.epoxy; import com.airbnb.epoxy.EpoxyDataBindingPattern; import com.airbnb.epoxy.EpoxyDataBindingLayouts; package-info.java
@EpoxyDataBindingLayouts @EpoxyDataBindingLayouts({R.layout.header_view, . . .}) header_view.xml HeaderViewBindingModel_.java Epoxy
४උྃʂ
̎. CellΛ࡞͢Δ
CellΛ࡞͢Δ <?xml version=“1.0” encoding=“utf-8”?> <layout> <data> <variable name=“cityName” type=“String” />
</data> <LinearLayout . . .> <TextView . . . android:text=“@{cityName}” /> </LinearLayout> </layout> epoxy_layout_header.xml
CellΛ࡞͢Δ <?xml version=“1.0” encoding=“utf-8”?> <layout> <data> <variable name=“cityName” type=“String” />
</data> <LinearLayout . . .> <TextView . . . android:text=“@{cityName}” /> </LinearLayout> epoxy_layout_header.xml override fun buildModels(city: City) { headerView { id(“header view”) cityName(city.name) } linkView { id(“link view”) onClick { _ -> callbacks.onLinkClick() } } // . . . . SampleController.kt
CellΛ࡞͢Δ <?xml version=“1.0” encoding=“utf-8”?> <layout> <data> <variable name=“cityName” type=“String” />
</data> <LinearLayout . . .> <TextView . . . android:text=“@{cityName}” /> </LinearLayout> epoxy_layout_header.xml override fun buildModels(city: City) { headerView { id(“header view”) cityName(city.name) } linkView { id(“link view”) onClick { _ -> callbacks.onLinkClick() } } // . . . . SampleController.kt
Build !
epoxy_layout_header.xml Epoxy HeaderBindingModel_.java HeaderBindingModel_.java͕ੜʂ
3. ControllerΛ࡞͢Δ
class SampleController: TypedEpoxyController<City>() { override fun buildModels(city: City?) { //
͜͜ͰViewΛ࡞Δ . . . . } } SampleController.kt Controller
class SampleController: TypedEpoxyController<City>() { override fun buildModels(city: City?) { //
͜͜ͰViewΛ࡞Δ . . . . } } SampleController.kt Controller
class SampleController: TypedEpoxyController<City>() { override fun buildModels(city: City?) { //
͜͜ͰViewΛ࡞Δ . . . . } } SampleController.kt Controller
class SampleController: TypedEpoxyController<City>() { override fun buildModels(city: City?) { //
͜͜ͰViewΛ࡞Δ . . . . } } SampleController.kt Controller
class SampleController: TypedEpoxyController<City>() { override fun buildModels(city: City?) { //
͜͜ͰViewΛ࡞Δ . . . . } } SampleController.kt Controller
ViewΛ࡞͍ͬͯ͘
Controller epoxy_layout_header.xml epoxy_layout_link_view.xml
Controller epoxy_layout_header.xml epoxy_layout_link_view.xml Build !!
Controller HeaderBindingModel_.java LinkViewBindingModel_.java
override fun buildModels(city: City) { header { id(“header view”) cityName(city.name)
description(city.description) } linkView { id(“link view”) onClick { _ -> callbacks.onLinkClick() } } // . . . . Controller HeaderBindingModel_.java LinkViewBindingModel_.java SampleController.kt
Controller HeaderBindingModel_.java LinkViewBindingModel_.java SampleController.kt override fun buildModels(city: City) { header
{ id(“header view”) cityName(city.name) description(city.description) } linkView { id(“link view”) onClick { _ -> callbacks.onLinkClick() } } // . . . .
Controller HeaderBindingModel_.java LinkViewBindingModel_.java SampleController.kt override fun buildModels(city: City) { header
{ id(“header view”) cityName(city.name) description(city.description) } linkView { id(“link view”) onClick { _ -> callbacks.onLinkClick() } } // . . . .
4. EpoxyRecyclerViewΛՃʂ
Fragment <?xml version=“1.0” encoding=“utf-8”?> <layout> <FrameLayout . . .> <com.airbnb.epoxy.EpoxyRecyclerView
. . . /> </FrameLayout> </layout> sample_fragment.xml
Fragment <?xml version=“1.0” encoding=“utf-8”?> <layout> <FrameLayout . . .> <com.airbnb.epoxy.EpoxyRecyclerView
. . . /> </FrameLayout> </layout> sample_fragment.xml
Fragment SampleFragment.kt class SampleFragment: Fragment() { val controller = SampleController()
var city = City(~) override fun onCreateView(~): View { . . . binding.epoxyRecyclerView.setController(controller) controller.setData(city) . . . } . . . }
Fragment SampleFragment.kt class SampleFragment: Fragment() { val controller = SampleController()
var city = City(~) override fun onCreateView(~): View { . . . binding.epoxyRecyclerView.setController(controller) controller.setData(city) . . . } . . . }
Fragment SampleFragment.kt class SampleFragment: Fragment() { val controller = SampleController()
var city = City(~) override fun onCreateView(~): View { . . . binding.epoxyRecyclerView.setController(controller) controller.setData(city) . . . } . . . }
ʂ
https://github.com/ShoMasegi/TutorialEpoxy ࠓճ࡞ͨ͠ͷ
؆୯ʹ࡞͢Δ͜ͱ͕Ͱ͖·ͨ͠ɻ ࣍ୈͰڽͬͨͷ͕ൺֱతָʹ࣮Ͱ͖ͦ͏ɻ ײ
͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ