Kotlin + DataBinding を使った RecyclerView の実装

Kotlin + DataBinding を使った RecyclerView の実装

3e283c497a74b6977f6721fd3506e092?s=128

jumperson

July 01, 2016
Tweet

Transcript

  1. Kotlin + DataBinding を使った RecyclerView の実装 第3 回Kotlin 勉強会 @

    Sansan @jumpersons
  2. 自己紹介 株式会社カカクコム でアプリエンジニア 以前はWeb エンジニア(.NET) 2015 年5 月よりiOS エンジニア 2016

    年5 月よりAndroid エンジニア
  3. 最初に教えてもらったこと ListView よりRecyclerView がいいよ。 DataBinding が便利だからMVVM がいいよ。

  4. Kotlin 良い RecyclerView + DataBinding で実装したら Kotlin で書いて良かったと思えた。 (Java だと辛そう。。。)

    Kotlin でどのように実装し、 どのように良かったご紹介。
  5. こういう画面求められませんか? リスト表示だけどView が微妙に違う。

  6. None
  7. 実装の方針 View のレイアウトはそれぞれ定義 ReyclerView を使う デー タはフラットに持つ

  8. View のレイアウトはそれぞれ定義

  9. None
  10. デー タはこのような構造で持つ s e a l e d c l

    a s s L i s t I t e m { a b s t r a c t f u n g e t T y p e ( ) : T y p e e n u m c l a s s T y p e ( v a l i d : I n t ) { C a p t i o n ( 1 0 ) , S u b C a p t i o n ( 2 0 ) , C a t e g o r y ( 3 0 ) ; c o m p a n i o n o b j e c t { f u n f r o m ( i d : I n t ) : T y p e { r e t u r n v a l u e s ( ) . f i r s t { i t . i d = = i d } } } } c l a s s C a p t i o n I t e m ( v a l t i t l e : S t r i n g ) : L i s t I t e m ( ) { o v e r r i d e f u n g e t T y p e ( ) : T y p e { r e t u r n T y p e . C a p t i o n } } c l a s s S u b C a p t i o n I t e m ( v a l t i t l e : S t r i n g ) : L i s t I t e m ( ) {
  11. RecyclerViewAdapter 主要なメソッド デー タの数を返す View の種類をInt で返す ViewHolder を返す(postion: Int

    がない) View にデー タをバインドする f u n g e t I t e m C o u n t ( ) f u n g e t I t e m V i e w T y p e ( p o s i t i o n : I n t ) : I n t f u n o n C r e a t e V i e w H o l d e r ( p a r e n t : V i e w G r o u p ? , v i e w T y p e : I n t ) : R e c y c l e r V i e w . V f u n o n B i n d V i e w H o l d e r ( h o l d e r : R e c y c l e r V i e w . V i e w H o l d e r ? , p o s i t i o n : I n t )
  12. RecyclerViewAdapter 実装 constructor sealed class のList でデー タを持つ c l

    a s s C a t e g o r y L i s t R e c y c l e r V i e w A d a p t e r ( p r i v a t e v a r i t e m s : L i s t < C a t e g o r y L i s t V i e w M o d e l . L i s t I t e m > ) : R e c y c l e r V i e w . A d a p t e r < R e c y c l e r V i e w . V i e w H o l d e r > ( ) { }
  13. RecyclerViewAdapter 実装 fun getItemCount フラットなリストで持っているので返すだけ o v e r r

    i d e f u n g e t I t e m C o u n t ( ) = i t e m s . c o u n t ( )
  14. RecyclerViewAdapter 実装 fun getItemViewType enum のid を返す o v e

    r r i d e f u n g e t I t e m V i e w T y p e ( p o s i t i o n : I n t ) : I n t { v a l i t e m = i t e m s [ p o s i t i o n ] r e t u r n i t e m . g e t T y p e ( ) . i d }
  15. RecyclerViewAdapter 実装 fun onCreateViewHolder enum 毎にViewHolder を返す o v e

    r r i d e f u n o n C r e a t e V i e w H o l d e r ( p a r e n t : V i e w G r o u p ? , v i e w T y p e : I n t ) : R e c y c l e r V p a r e n t ? : r e t u r n n u l l v a l i t e m T y p e = C a t e g o r y L i s t V i e w M o d e l . L i s t I t e m . T y p e . f r o m ( v i e w T y p e ) w h e n ( i t e m T y p e ) { C a t e g o r y L i s t V i e w M o d e l . L i s t I t e m . T y p e . C a p t i o n - > { v a l b i n d i n g = C a p t i o n I t e m B i n d i n g . i n f l a t e ( L a y o u t I n f l a t e r . f r o m ( r e t u r n C a p t i o n I t e m V i e w H o l d e r ( b i n d i n g ) } C a t e g o r y L i s t V i e w M o d e l . L i s t I t e m . T y p e . S u b C a p t i o n - > { v a l b i n d i n g = S u b C a p t i o n I t e m B i n d i n g . i n f l a t e ( L a y o u t I n f l a t e r . f r r e t u r n S u b C a p t i o n I t e m V i e w H o l d e r ( b i n d i n g ) } C a t e g o r y L i s t V i e w M o d e l . L i s t I t e m . T y p e . C a t e g o r y - > { v a l b i n d i n g = C a t e g o r y I t e m B i n d i n g . i n f l a t e ( L a y o u t I n f l a t e r . f r o m
  16. RecyclerViewAdapter 実装 ViewHolder はこんな感じ p r i v a t

    e c l a s s C a p t i o n I t e m V i e w H o l d e r ( v a l b i n d i n g : C a p t i o n I t e m B i n d i n g ) : R e c y c l e r V i e w . V i e w H o l d e r ( b i n d i n g . r o o t ) { } p r i v a t e c l a s s S u b C a p t i o n I t e m V i e w H o l d e r ( v a l b i n d i n g : S u b C a p t i o n I t e m B i n d i n g ) : R e c y c l e r V i e w . V i e w H o l d e r ( b i n d i n g . r o o t ) { } p r i v a t e c l a s s C a t e g o r y I t e m V i e w H o l d e r ( v a l b i n d i n g : C a t e g o r y I t e m B i n d i n g ) : R e c y c l e r V i e w . V i e w H o l d e r ( b i n d i n g . r o o t ) { }
  17. RecyclerViewAdapter 実装 fun onBindViewHolder ViewHolder とデー タをCast してデー タをバインド o

    v e r r i d e f u n o n B i n d V i e w H o l d e r ( h o l d e r : R e c y c l e r V i e w . V i e w H o l d e r ? , p o s i t i o n : I n t v a l i t e m = i t e m s [ p o s i t i o n ] w h e n { h o l d e r i s C a p t i o n I t e m V i e w H o l d e r & & i t e m i s C a t e g o r y L i s t V i e w M o d e l . @ S u p p r e s s ( " M I S S I N G _ D E P E N D E N C Y _ C L A S S " ) h o l d e r . b i n d i n g . i t e m = i t e m } h o l d e r i s S u b C a p t i o n I t e m V i e w H o l d e r & & i t e m i s C a t e g o r y L i s t V i e w M o d @ S u p p r e s s ( " M I S S I N G _ D E P E N D E N C Y _ C L A S S " ) h o l d e r . b i n d i n g . i t e m = i t e m } h o l d e r i s C a t e g o r y I t e m V i e w H o l d e r & & i t e m i s C a t e g o r y L i s t V i e w M o d e l @ S u p p r e s s ( " M I S S I N G _ D E P E N D E N C Y _ C L A S S " )
  18. 良かったところ ViewType のInt の管理がsealed class の宣言のところでま とめられ見通しが良い View の種類が増える場合はパター ンマッチの網羅チェ

    ックがかかる RecyclerView の作り上Cast は仕方ないがKotlin はCast が 優秀なので実装しやすい
  19. 残念だったところ enum で一意の値を持てない onBindViewHolder でViewHolder とデー タのキャストが 必要で網羅チェックができない ViewHolder の判定にViewType:Int

    は辛い
  20. ご静聴ありがとうございました。 https://github.com/jumperson/Kotlin-sansan-20160701