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

東急カードプラスのCompose Preview活用事例

Avatar for Ritsuki Otsuka Ritsuki Otsuka
September 25, 2024

東急カードプラスのCompose Preview活用事例

DroidKaigi.onCompletion { 2024@Online } https://yumemi.connpass.com/event/329691/

Avatar for Ritsuki Otsuka

Ritsuki Otsuka

September 25, 2024
Tweet

Other Decks in Technology

Transcript

  1. 自己紹介 2 • 大塚 立樹 / Ritsuki Otsuka • 東急株式会社

    URBAN HACKS • Androidエンジニア(3年目) • 「東急カードプラス」Androidアプリの開発を担当
  2. 東急カードプラス 3 • TOKYU CARDのご利用明細や、TOKYU POINT CARDのポイント残高など を確認できる • 東急沿線エリアのタイムリーでおトクな情報や、ポイントがお得に貯まる方法など

    も紹介 • 2023年3月にリニューアルリリース • 技術スタック • Jetpack Compose (100%) • Jetpack Navigation • Kotlin Coroutines and Flow • Dagger Hilt • etc…
  3. 東急カードプラスの画面実装 9 1. TOKYU POINT残高 → TokyuPointSection 2. お支払い額 →

    PaymentAmountSection 3. ご利用実績 → MonthlyPaymentsSection 4. ピックアップ → PickupSection 5. かしこいポイントの貯め方 → PointEarningTipsSection
  4. 東急カードプラスの画面実装 10 1. TOKYU POINT残高 → TokyuPointSection 2. お支払い額 →

    PaymentAmountSection 3. ご利用実績 → MonthlyPaymentsSection 4. ピックアップ → PickupSection 5. かしこいポイントの貯め方 → PointEarningTipsSection ➡ SectionごとにUI Stateを作成
  5. 東急カードプラスの画面実装 11 data class HomeUiState( // 1. TOKYU POINT残高 val

    tokyuPointSectionUiState: TokyuPointSectionUiState, // 2. お支払い額 val paymentAmountSectionUiState: PaymentAmountSectionUiState?, // 3. ご利用実績 val monthlyPaymentsSectionUiState: MonthlyPaymentsSectionUiState? // 4. ピックアップ val pickupSectionUiState: PickupSectionUiState?, // 5. かしこいポイントの貯め方 val pointEarningTipsSectionUiState: PointEarningTipsSectionUiState ) : HomeUiState
  6. 複雑なUI Stateのパターンを Previewする 17 TOKYU POINT残高表示の基本UIパターン 1. ポイント表示状態 2. ポイント非表示状態

    3. ローディング状態      ❎ 時間ごとの UIパターン 1. 朝(4:00〜10:59) 2. 昼(11:00〜16:59) 3. 夜(17:00〜3:59)
  7. 複雑なUI Stateのパターンを Previewする 21 class TokyuPointSectionPreviewParameterProvider : PreviewParameterProvider<TokyuPointSectionUiState> { override

    val values: Sequence<TokyuPointSectionUiState> = sequenceOf( // ローディング状態 TokyuPointSectionUiState.Loading, // ポイント表示状態 x 時間帯 TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Morning), TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Noon), TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Night), // ポイント非表示状態 x 時間帯 TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Morning), TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Noon), TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Night) ) }
  8. 複雑なUI Stateのパターンを Previewする 22 class TokyuPointSectionPreviewParameterProvider : PreviewParameterProvider<TokyuPointSectionUiState> { override

    val values: Sequence<TokyuPointSectionUiState> = sequenceOf( // ローディング状態 TokyuPointSectionUiState.Loading, // ポイント表示状態 x 時間帯 TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Morning), TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Noon), TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Night), // ポイント非表示状態 x 時間帯 TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Morning), TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Noon), TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Night) ) }
  9. 複雑なUI Stateのパターンを Previewする 23 class TokyuPointSectionPreviewParameterProvider : PreviewParameterProvider<TokyuPointSectionUiState> { override

    val values: Sequence<TokyuPointSectionUiState> = sequenceOf( // ローディング状態 TokyuPointSectionUiState.Loading, // ポイント表示状態 x 時間帯 TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Morning), TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Noon), TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Night), // ポイント非表示状態 x 時間帯 TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Morning), TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Noon), TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Night) ) }
  10. 複雑なUI Stateのパターンを Previewする 24 class TokyuPointSectionPreviewParameterProvider : PreviewParameterProvider<TokyuPointSectionUiState> { override

    val values: Sequence<TokyuPointSectionUiState> = sequenceOf( // ローディング状態 TokyuPointSectionUiState.Loading, // ポイント表示状態 x 時間帯 TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Morning), TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Noon), TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Night), // ポイント非表示状態 x 時間帯 TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Morning), TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Noon), TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Night) ) }
  11. 複雑なUI Stateのパターンを Previewする 25 class TokyuPointSectionPreviewParameterProvider : PreviewParameterProvider<TokyuPointSectionUiState> { override

    val values: Sequence<TokyuPointSectionUiState> = sequenceOf( // ローディング状態 TokyuPointSectionUiState.Loading, // ポイント表示状態 x 時間帯 TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Morning), TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Noon), TokyuPointSectionUiState.PointAmountVisible(pointAmount = 1000, timePeriod = TimePeriod.Night), // ポイント非表示状態 x 時間帯 TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Morning), TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Noon), TokyuPointSectionUiState.PointAmountHidden(pointAmount = 1000, timePeriod = TimePeriod.Night) ) }
  12. カスタムマルチプレビューアノテーション 29 @Preview(name = "1 デフォルト") @Preview( name = "2

    最大フォントサイズ", fontScale = 2.0f ) @Preview(name = "3 Foldable", device = Devices.FOLDABLE) annotation class HachiPreviews 1. 通常端末サイズ 2. 最大フォントサイズ 3. 折りたたみ端末
  13. カスタムマルチプレビューアノテーション 30 @Preview(name = "1 デフォルト") @Preview( name = "2

    最大フォントサイズ", fontScale = 2.0f ) @Preview(name = "3 Foldable", device = Devices.FOLDABLE) annotation class HachiPreviews
  14. カスタムマルチプレビューアノテーション 31 @Preview(name = "1 デフォルト") @Preview( name = "2

    最大フォントサイズ", fontScale = 2.0f ) @Preview(name = "3 Foldable", device = Devices.FOLDABLE) annotation class HachiPreviews
  15. カスタムマルチプレビューアノテーション 32 @Preview(name = "1 デフォルト") @Preview( name = "2

    最大フォントサイズ", fontScale = 2.0f ) @Preview(name = "3 Foldable", device = Devices.FOLDABLE) annotation class HachiPreviews
  16. カスタムマルチプレビューアノテーション 33 @Preview(name = "1 デフォルト") @Preview( name = "2

    最大フォントサイズ", fontScale = 2.0f ) @Preview(name = "3 Foldable", device = Devices.FOLDABLE) annotation class HachiPreviews