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
860
今更ながらEpoxy / Lateinit Epoxy
今更ながらEpoxyを触ってみました。
Sho Masegi
November 06, 2018
Tweet
Share
More Decks by Sho Masegi
See All by Sho Masegi
独自の共通認証基盤を用いているサービスでアカウント削除機能を提供したときの道程
shomasegi
1
2.9k
Migrate Swift 4.2 to 5.2
shomasegi
4
870
Material Components ことはじめ / Get Started Material Components
shomasegi
0
780
Other Decks in Technology
See All in Technology
LayerX QA Night#1
koyaman2
0
300
2025年 山梨の技術コミュニティを振り返る
yuukis
0
140
Snowflake Industry Days 2025 Nowcast
takumimukaiyama
0
160
202512_AIoT.pdf
iotcomjpadmin
0
180
Claude Skillsの テスト業務での活用事例
moritamasami
1
130
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
10k
人工知能のための哲学塾 ニューロフィロソフィ篇 第零夜 「ニューロフィロソフィとは何か?」
miyayou
0
270
産業的変化も組織的変化も乗り越えられるチームへの成長 〜チームの変化から見出す明るい未来〜
kakehashi
PRO
0
130
戰略轉變:從建構 AI 代理人到發展可擴展的技能生態系統
appleboy
0
170
SES向け、生成AI時代におけるエンジニアリングとセキュリティ
longbowxxx
0
280
投資戦略を量産せよ 2 - マケデコセミナー(2025/12/26)
gamella
0
570
AI: The stuff that nobody shows you
jnunemaker
PRO
1
130
Featured
See All Featured
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
57
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
32
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.1k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.3k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
3.3k
Un-Boring Meetings
codingconduct
0
170
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
530
Site-Speed That Sticks
csswizardry
13
1k
Automating Front-end Workflow
addyosmani
1371
200k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2k
Ethics towards AI in product and experience design
skipperchong
1
150
Measuring & Analyzing Core Web Vitals
bluesmoon
9
720
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 ࠓճ࡞ͨ͠ͷ
؆୯ʹ࡞͢Δ͜ͱ͕Ͱ͖·ͨ͠ɻ ࣍ୈͰڽͬͨͷ͕ൺֱతָʹ࣮Ͱ͖ͦ͏ɻ ײ
͋Γ͕ͱ͏͍͟͝·ͨ͠ɻ