$30 off During Our Annual Pro Sale. View Details »

No more Adapter with Epoxy and Data Binding

No more Adapter with Epoxy and Data Binding

Takuji Nishibayashi

March 01, 2019
Tweet

More Decks by Takuji Nishibayashi

Other Decks in Technology

Transcript

  1. No more Adapter with Epoxy and
    Data Binding
    @takuji31
    ژ౎Dev͔;͐ #5

    View Slide

  2. ࣗݾ঺հ

    View Slide

  3. ࣗݾ঺հ
    • @takuji31 id:takuji31
    • Takuji Nishibayashi
    • Hatena Co., Ltd.
    • App Team
    • δϟϯϓϧʔΩʔʂ
    • ίϛοΫDAYS
    • ΧΫϤϜ

    View Slide

  4. ࣗݾ঺հ
    • Android
    • Kotlin

    !
    https://blog.takuji31.jp

    "
    https://nazuna.takuji31.jp

    # $
    https://photo.takuji31.jp

    View Slide

  5. RecyclerView

    View Slide

  6. ࢖ͬͯͳ͍ਓ͍·ͤΜΑͶʁ

    View Slide

  7. ViewHolder + Adapter

    View Slide

  8. ΦϓγϣϯͰ DiffUtil

    View Slide

  9. blog.takuji31.jp/entry/kanmoba17

    View Slide

  10. ෳࡶͳը໘

    View Slide

  11. View Slide

  12. Ͳ͏࣮ݱ͢Δʁ

    View Slide

  13. खͰؤுΔ

    View Slide

  14. ViewHolderΛview type͝ͱʹ࡞Δ

    View Slide

  15. onCreateViewHolderͰ֘౰͢Δ
    ViewHolderΛ࡞Δ

    View Slide

  16. onBindViewHolderͰViewHolderͷ
    ܕΛݟͯ஋Λઃఆ

    View Slide

  17. มߋݕ஌

    View Slide

  18. DiffUtilͰؤுΔ

    View Slide

  19. !

    View Slide

  20. Section Library

    View Slide

  21. ※ ͍͔ͭ͘ϥΠϒϥϦʔ͕͋Γ·͢
    ͕Ұൠతͳ࿩Ͱ͢

    View Slide

  22. view typeͷ୅ΘΓʹSectionͱ͍͏
    ΫϥεΛ࢖͏

    View Slide

  23. Section
    class WorkSection(val items:List): Section() {
    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)
    }
    }

    View Slide

  24. Adapter
    val adapter = Adapter()
    adapter.addSection(BannerSection(works))
    adapter.addSection(WorkSection(works.take(10)))
    adapter.addSection(EntrySection(works))
    adapter.addSection(WorkSection(works.drop(10)))

    View Slide

  25. ύοͱݟ؆୯ͦ͏

    View Slide

  26. ΫϦοΫΠϕϯτͷ఻ୡͲ͏͢Δ…ʁ
    class WorkSection(val items:List, val onClick: (Work) -> Unit): Section() {
    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() }
    }
    }

    View Slide

  27. 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)))

    View Slide

  28. ͪΐͬͱ໘౗

    View Slide

  29. ͦ΋ͦ΋

    View Slide

  30. Adapter
    -> Section
    -> ViewHolder

    View Slide

  31. ֊૚͕૿͑Δ

    View Slide

  32. ঢ়ଶΛόϥόϥʹ͍࣋ͬͯͨΓ͢Δ
    ͱ෮ݩͰࢮ͵

    View Slide

  33. Ϋϥε਺૿͑Δ

    View Slide

  34. ॳݟͰΊͬͪΌΉ͍ͣ

    View Slide

  35. Epoxy

    View Slide

  36. github.com/airbnb/epoxy

    View Slide

  37. No more

    View Slide

  38. ViewHolder

    View Slide

  39. notifyDataSetChanged()

    View Slide

  40. Adapter

    View Slide

  41. Carousel support

    View Slide

  42. Data Binding Friendly

    View Slide

  43. Kotlin DSL support!!!

    View Slide

  44. 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"
    }

    View Slide

  45. package-info.java
    @EpoxyDataBindingPattern(rClass = R.class, layoutPrefix = "recycler")
    package jp.takuji31.epoxyexample;
    import com.airbnb.epoxy.EpoxyDataBindingPattern;

    View Slide

  46. recycler_item_work.xml





    android:onClick="@{onClick}">

    app:imageUri="@{work.imageUri}"/>
    android:text="@{work.title}"/>



    View Slide

  47. Activity or Fragment
    recyclerView.withModels {
    works.forEach { work ->
    itemWork {
    id("work_${work.id}")
    work(work)
    }
    }
    }

    View Slide

  48. View Slide

  49. !

    View Slide

  50. Carousel

    View Slide

  51. Carousel
    recyclerView.withModels {
    carousel {
    id("entryCaroucel")
    withModelsFrom(entries) { entry ->
    ItemEntryBindingModel_()
    .id("entry_${entry.id}")
    .entry(entry)
    }
    }
    }

    View Slide

  52. View Slide

  53. ؆୯͗͢Ͱ͸

    View Slide

  54. ෳࡶͳϨΠΞ΢τ

    View Slide

  55. ෳࡶͳϨΠΞ΢τ
    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)
    }
    }

    View Slide

  56. ෳࡶͳϨΠΞ΢τ
    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)
    }
    }

    View Slide

  57. ׬੒ʂ

    View Slide

  58. https://github.com/takuji31/epoxy-
    example

    View Slide

  59. Enjoy RecyclerView life

    View Slide

  60. !
    ࠾༻৘ใ

    View Slide

  61. גࣜձࣾ͸ͯͳͰ͸ɺ
    ͱ΋ʹʮ௅ઓʯͰ͖Δ
    ஥ؒΛืू͍ͯ͠·͢

    View Slide

  62. ͜ΜͳਓΛ୳͍ͯ͠·͢
    • AndroidΞϓϦΛ࡞Γ͍ͨਓ
    • iOSΞϓϦΛ࡞Γ͍ͨਓ
    • ͋Δ͍͸྆ํ
    • ͳΜͳΒαʔόʔαΠυ΋

    View Slide

  63. https://hatenacorp.jp/recruit/

    View Slide