Upgrade to Pro — share decks privately, control downloads, hide ads and more …

トップ画面のRecyclerViewにComposeを一部導入した話/ #nikkei_tech_talk

トップ画面のRecyclerViewにComposeを一部導入した話/ #nikkei_tech_talk

2023/06/15開催、NIKKEI Tech Talk #8登壇資料です #nikkei_tech_talk
タイトルは「トップ画面のRecyclerViewにComposeを一部導入した話」です
https://nikkei.connpass.com/event/284090/

More Decks by 日本経済新聞社 エンジニア採用事務局

Other Decks in Technology

Transcript

  1. 2023/6/15
    日本経済新聞社 Androidチーム 篠原裕矢
    トップ画面の RecyclerView に
    Compose を一部導入した話

    View Slide

  2. ハッシュタグ #nikkei_tech_talk
    自己紹介
    2
    ● 2020 年 4 月に日経入社(新卒 4 年目)
    ● Android チームで日経電子版と紙面ビューアーを開発
    ● ラーメンとカレーと日本酒が好き

    View Slide

  3. ハッシュタグ #nikkei_tech_talk
    1. 電子版トップ画面構成について
    2. Jetpack Compose の導入ステップ
    3. RecyclerView へ Compose を導入する実装方法
    アジェンダ
    3

    View Slide

  4. ハッシュタグ #nikkei_tech_talk
    ● 基本的な RecyclerView の仕組み
    ○ onBindViewHolder 、onCreateViewHolder のタイミング
    ● Compose の LazyColumn 、 LazyRow の仕組み
    ● 複雑な UI を Compose で記述する方法
    今日話さないこと
    4

    View Slide

  5. ハッシュタグ #nikkei_tech_talk
    1. 電子版トップ画面構成について
    2. Jetpack Compose の導入ステップ
    3. RecyclerView へ Compose を導入する実装方法
    アジェンダ
    5

    View Slide

  6. ハッシュタグ #nikkei_tech_talk
    電子版トップの画面例( RecyclerView )
    6

    View Slide

  7. ハッシュタグ #nikkei_tech_talk 7
    現時点でどこが Compose ?

    View Slide

  8. ハッシュタグ #nikkei_tech_talk
    Compose を導入済みのアイテム
    8
    ヘッダー
    画像バナー

    View Slide

  9. ハッシュタグ #nikkei_tech_talk
    電子版トップ画面の特徴
    9
    ● ユーザーの PV 数が最も多い画面の 1 つ
    ● 重要度の高いニュースが並ぶ
    ● 変更頻度が高い
    ● RecyclerView の Adapter で管理する表示アイテムが 20 種
    類近くある
    ○ 記事、バナー、ヘッダー、広告など

    View Slide

  10. ハッシュタグ #nikkei_tech_talk
    1. 電子版トップ画面構成について
    2. Jetpack Compose の導入ステップ
    3. RecyclerView へ Compose を導入する実装方法
    アジェンダ
    10

    View Slide

  11. ハッシュタグ #nikkei_tech_talk 11
    Android View
    RecyclerView
    Android View
    Android View
    ComposeView
    RecyclerView
    Android View
    Android View
    ComposeView
    LazyColumn
    ComposeView
    ComposeView
    導入前 部分的導入 完全移行
    Jetpack Compose の導入ステップ

    View Slide

  12. ハッシュタグ #nikkei_tech_talk
    Jetpack Compose の導入ステップ
    12
    Android View
    RecyclerView
    Android View
    Android View
    ComposeView
    RecyclerView
    Android View
    Android View
    ComposeView
    LazyColumn
    ComposeView
    ComposeView
    紹介
    導入前 部分的導入 完全移行

    View Slide

  13. ハッシュタグ #nikkei_tech_talk
    Compose 導入前の構成
    13
    ● ViewBinding + ListAdapter の構成
    ○ Groupie や Epoxy などのサードパーティライブラリを使わない素
    の RecyclerView
    ● 表示アイテムのレイアウトはすべて xml で記述
    ○ 20種類近くの表示アイテムあり

    View Slide

  14. ハッシュタグ #nikkei_tech_talk
    Compose 部分的導入後の構成
    14
    ● ViewBinding + AbstractComposeView + ListAdapter の
    構成
    ● 表示アイテムのレイアウトは xml または Compose で記述
    ○ 20種類近くの表示アイテムあり
    ● アイテム管理などの仕組みは RecyclerView を踏襲

    View Slide

  15. ハッシュタグ #nikkei_tech_talk
    なぜ部分的に導入したか
    15
    ● Full Compose な画面に一括で変更するには工数がかかる
    ● 複雑な UI のアイテムも多く、変更頻度が高い画面である
    ○ 20種類近くの UI パーツがある
    ○ 最も訪問される画面なのでリスクが高い
    ● Compose の技術潮流に乗るべく、安全に導入して少しずつ移
    行したい
    ● 作った UI を別の Compose な画面において再利用可能

    View Slide

  16. ハッシュタグ #nikkei_tech_talk
    1. 電子版トップ画面構成について
    2. Jetpack Compose の導入ステップ
    3. RecyclerView へ Compose を導入する実装方法
    アジェンダ
    16

    View Slide

  17. ハッシュタグ #nikkei_tech_talk
    事前準備 〜ライブラリアップデート〜
    17
    ● Compose UI のバージョンを 1.2.0 以上に上げる
    ● RecyclerView のバージョンを 1.3.0 以上に上げる
    ● dependencies にて下記記述
    implementation "androidx.compose.ui:ui:1.2.0"
    implementation "androidx.recyclerview:recyclerview:1.3.0"

    View Slide

  18. ハッシュタグ #nikkei_tech_talk
    事前準備 〜ライブラリアップデート〜
    18
    ● RecyclerView と Compose が協調して動作するようになり、
    View が画面外に移動したときの再利用が効率的になる
    ● 詳しくは各ライブラリのリリースノート👇
    ○ https://developer.android.com/jetpack/androidx/releases/compose-
    ui#1.2.0-alpha06
    ○ https://developer.android.com/jetpack/androidx/releases/recyclervie
    w#recyclerview-1.3.0-beta01

    View Slide

  19. ハッシュタグ #nikkei_tech_talk
    事前準備 〜ライブラリアップデート〜
    19
    ● Compose UI 1.2.0
    ○ RecyclerView などの PoolingContainer を適切に処理する
    DisposeOnDetachedFromWindowOrReleasedFromPool と
    いう新しい ViewCompositionStrategy が追加された
    ● RecyclerView 1.3.0
    ○ PoolingContainer の修正など、Compose UI 1.2.0 に対応した
    View 再利用の実装

    View Slide

  20. ハッシュタグ #nikkei_tech_talk
    実装方法 〜 ViewHolder の作成 〜
    20
    ● ViewBinding 用の ViewHolder と Compose 用の ViewHolder
    ● Compose 用 のViewHolder には AbstractComposeView
    を渡す
    class ViewBindingHolder(
    val binding: ViewBinding,
    ) : RecyclerView.ViewHolder(binding.root)
    class ComposeViewHolder(
    val abstractComposeView: AbstractComposeView,
    ) : RecyclerView.ViewHolder(abstractComposeView)

    View Slide

  21. ハッシュタグ #nikkei_tech_talk
    実装方法
    21
    ● onCreateViewHolder で ViewType に応じて
    ViewBindingHolder or ComposeViewHolder を返す
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    return when (ViewType.from(viewType)) {
    ViewType.HEADLINE_ARTICLE -> {
    val layoutInflater = LayoutInflater.from(parent.context)
    ViewBindingHolder(ArticleBinding.inflate(layoutInflater, parent, false))
    }
    ViewType.HEADLINE_HEADER -> {
    ComposeViewHolder(HeaderComposeView(parent.context))
    }
    }
    }

    View Slide

  22. ハッシュタグ #nikkei_tech_talk
    実装方法
    22
    ● onBindViewHolder で型チェックをする
    ● ViewBindingHolder or ComposeViewHolder で bind
    処理を実行する
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
    val item = getItem(position)
    when (holder) {
    is ViewBindingHolder -> holder.bind(item)
    is ComposeViewHolder -> holder.bind(item)
    }
    }

    View Slide

  23. ハッシュタグ #nikkei_tech_talk
    実装方法
    23
    ● ヘッダーの ComposeView に定義した bind メソッドを呼ぶ
    fun ComposeViewHolder.bind(item: NewsItem) {
    // Composeで実装されているRecyclerViewのアイテムがbind対象
    when (item) {
    is NewsItem.HeadlineHeader -> {
    (abstractComposeView as HeaderComposeView).bind(item.headerItem)
    }
    is NewsItem.HeadlineBanner -> {
    (abstractComposeView as BannerComposeView).bind(item.bannerItem)
    }
    else -> {}
    }
    }

    View Slide

  24. ハッシュタグ #nikkei_tech_talk
    class HeaderComposeView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0,
    ) : AbstractComposeView(context, attrs, defStyle) {
    private var headerItem by mutableStateOf(null)
    @Composable
    override fun Content() {
    AppTheme {
    Header(
    headerItem = headerItem,
    )
    }
    }
    fun bind(headerItem: HeaderItem) {
    this.headerItem = headerItem
    }
    }
    実装方法 〜 ヘッダーの ComposeView 〜
    24
    Content() の中で
    Composable 関数が書ける

    View Slide

  25. ハッシュタグ #nikkei_tech_talk
    実装方法
    25
    @Composable
    fun Header(
    headerItem: HeaderItem?,
    modifier: Modifier = Modifier,
    ) {
    // Text、Button、RowなどのComposable関数を自由に書いてレイアウトを作成する
    }
    トップ画面以外にも
    レイアウトを流用できる

    View Slide

  26. ハッシュタグ #nikkei_tech_talk
    まとめ
    26
    ● RecyclerView に Compose を導入していく方法を紹介しまし

    ● 部分的な導入は実装コストも低いのでぜひ皆さんもやっていきま
    しょう💪
    ● Compose を例としてモダンな技術をプロダクトに入れていく
    チームの流れがあり、楽しい開発ができます!

    View Slide

  27. ハッシュタグ #nikkei_tech_talk 27
    ご清聴ありがとうございました

    View Slide