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
今更ながらEpoxy / Lateinit Epoxy
Search
Sho Masegi
November 06, 2018
Technology
2
840
今更ながらEpoxy / Lateinit Epoxy
今更ながらEpoxyを触ってみました。
Sho Masegi
November 06, 2018
Tweet
Share
More Decks by Sho Masegi
See All by Sho Masegi
独自の共通認証基盤を用いているサービスでアカウント削除機能を提供したときの道程
shomasegi
1
2.6k
Migrate Swift 4.2 to 5.2
shomasegi
4
840
Material Components ことはじめ / Get Started Material Components
shomasegi
0
760
Other Decks in Technology
See All in Technology
生成AI時代の開発組織・技術・プロセス 〜 ログラスの挑戦と考察 〜
itohiro73
1
430
2025-07-06 QGIS初級ハンズオン「はじめてのQGIS」
kou_kita
0
160
マーケットプレイス版Oracle WebCenter Content For OCI
oracle4engineer
PRO
3
960
AWS認定を取る中で感じたこと
siromi
1
170
Glacierだからってコストあきらめてない? / JAWS Meet Glacier Cost
taishin
1
150
KubeCon + CloudNativeCon Japan 2025 Recap by CA
ponkio_o
PRO
0
290
AIとともに進化するエンジニアリング / Engineering-Evolving-with-AI_final.pdf
lycorptech_jp
PRO
0
150
本が全く読めなかった過去の自分へ
genshun9
0
890
FOSS4G 2025 KANSAI QGISで点群データをいろいろしてみた
kou_kita
0
390
KubeCon + CloudNativeCon Japan 2025 Recap Opening & Choose Your Own Adventureシリーズまとめ
mmmatsuda
0
260
PO初心者が考えた ”POらしさ”
nb_rady
0
190
論文紹介:LLMDet (CVPR2025 Highlight)
tattaka
0
300
Featured
See All Featured
A designer walks into a library…
pauljervisheath
207
24k
Intergalactic Javascript Robots from Outer Space
tanoku
271
27k
Designing Experiences People Love
moore
142
24k
Speed Design
sergeychernyshev
32
1k
Rails Girls Zürich Keynote
gr2m
94
14k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
810
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
30
2.1k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
Unsuck your backbone
ammeep
671
58k
Adopting Sorbet at Scale
ufuk
77
9.4k
The World Runs on Bad Software
bkeepers
PRO
69
11k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
730
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 ࠓճ࡞ͨ͠ͷ
؆୯ʹ࡞͢Δ͜ͱ͕Ͱ͖·ͨ͠ɻ ࣍ୈͰڽͬͨͷ͕ൺֱతָʹ࣮Ͱ͖ͦ͏ɻ ײ
͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ