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

基礎から学ぶ大画面対応(Learning Large-Screen Support from ...

Avatar for Tomoya Miwa Tomoya Miwa
September 08, 2025

基礎から学ぶ大画面対応(Learning Large-Screen Support from the Ground Up)

〜「Large screen differentiated」認定アプリの開発知見〜(— Development Insights from a “Large screen differentiated”-Certified App —)

Avatar for Tomoya Miwa

Tomoya Miwa

September 08, 2025
Tweet

More Decks by Tomoya Miwa

Other Decks in Programming

Transcript

  1. 基礎から学ぶ大画面対応 (Learning Large-Screen Support from the Ground Up) 〜「Large screen

    differentiated」認定アプリの開発知見〜 (— Development Insights from a “Large screen differentiated”- Certified App —) DroidKaigi 2025 / tomoya0x00 1
  2. 自己紹介 (Self Introduction) tomoya0x00 - X, GitHub, Zenn U-NEXT Co.,

    Ltd Research & Development 過去の登壇 (Past Presentations) DroidKaigi 2018, 2019 DevFest & Android Dev Summit Japan 2022 5
  3. About U-NEXT App - 1/3 VOD + Book のアプリ (VOD

    + Book app) 2024 年に フル Compose でリニューアル (Renewed with full Compose in 2024) 6
  4. About U-NEXT App - 2/3 Google Play Best Of Awards

    2022 「ベストアプリ 2022」と「タブレット部門 アプリ カテゴリ 大賞」のダブル受賞 (Double Award: "Best App 2022" and "Tablet Category Grand Prize") 2024 「マルチデバイス部門 アプリカテゴリ 大賞」を受賞 ("Multi-Device Category Grand Prize" Award) 7
  5. About U-NEXT App - 3/3 Large screen app quality 2022

    Large screen optimized 認定 (Large screen optimized Certified) 2025 日本 VOD アプリ初の Large screen differentiated 認定 (First Japanese VOD app certified as Large screen differentiated) 8
  6. 目次 (Agenda) 1. 大画面対応の重要性 (Importance of Large Screen Support) 2.

    大画面対応のサポートレベル (Large screen support levels) 3. View ベースアプリの大画面対応戦略 (Large Screen Strategy for View-based Apps) 4. 基本的な大画面対応 (Large screen ready) 5. 大画面向けに最適化 (Large screen optimized) 6. 更なる大画面対応 (Further Large Screen Support) 7. まとめ (Summary) 9
  7. 目次 (Agenda) 1. 大画面対応の重要性 (Importance of Large Screen Support) 2.

    大画面対応のサポートレベル (Large screen support levels) 3. View ベースアプリの大画面対応戦略 (Large Screen Strategy for View-based Apps) 4. 基本的な大画面対応 (Large screen ready) 5. 大画面向けに最適化 (Large screen optimized) 6. 更なる大画面対応 (Further Large Screen Support) 7. まとめ (Summary) 10
  8. Ignore orientation, resizability, and aspect ratio restrictions 画面の最小幅が 600dp 以上であれば、下記の制限が無視される

    (On displays with smallest width >= 600dp, the below restrictions no longer apply:) orientation resizability aspect ratio https://developer.android.com/about/versions/16/behavior-changes-16#ignore- orientation 13
  9. 一時的な opt-out (Temporary Opt-out) <activity ...> <property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY" android:value="true" />

    ... </activity> <application ...> <property android:name="android.window.PROPERTY_COMPAT_ALLOW_RESTRICTED_RESIZABILITY" android:value="true" /> </application> https://developer.android.com/about/versions/16/behavior-changes-16#temporary-opt- out 14
  10. Android release in 2026: Changes described above will be the

    baseline experience for large screen devices (smallest screen width >600dp) for apps that target API level 37. Developers will not have an option to opt-out. https://android-developers.googleblog.com/2025/01/orientation-and-resizability- changes-in-android-16.html 16
  11. With Android apps now running on a variety of devices

    (such as phones, tablets, foldables, desktops, cars, and TVs) and windowing modes on large screens (such as split screen and desktop windowing), developers should build Android apps that adapt to any screen and window size, regardless of device orientation. Paradigms like restricting orientation and resizability are too restrictive in today's multidevice world. https://developer.android.com/about/versions/16/behavior-changes-16#adaptive-layouts 18
  12. Android XR デバイス (Android XR Devices) スマホと比べて 広大な表示領域 (Vast display

    area compared to smartphones) スマホだけを考慮したデザインでは、この広大な表示領域を活かせない (Smartphone-only designs cannot utilize this vast display area) 20
  13. 目次 (Agenda) 1. 大画面対応の重要性 (Importance of Large Screen Support) 2.

    大画面対応のサポートレベル (Large screen support levels) 3. View ベースアプリの大画面対応戦略 (Large Screen Strategy for View-based Apps) 4. 基本的な大画面対応 (Large screen ready) 5. 大画面向けに最適化 (Large screen optimized) 6. 更なる大画面対応 (Further Large Screen Support) 7. まとめ (Summary) 23
  14. TIER 3 (basic) — Large screen ready 最低限動く (Basic functionality)

    TIER 2 (better) — Large screen optimized 快適に使える (Comfortable experience) TIER 1 (best) — Large screen differentiated 大画面を活かした体験を提供 (Large screen-first experience) https://developer.android.com/docs/quality-guidelines/large-screen-app-quality 25
  15. TIER 3 (basic) — Large screen ready 重要なタスクフローは完了可能 (Users can

    complete critical task flows) ユーザーエクスペリエンスは最適ではない (Less than optimal user experience) Configuration changes を適切に処理 (Handle configuration changes properly) 全画面で実行 (Full screen) レイアウトは理想的でない可能性あり (App layout might not be ideal) レターボックス表示なし (Not letterboxed) 外部入力デバイスの基本サポート (Basic support for external input devices) キーボード、マウス、トラックパッド、スタイラス (Keyboard, mouse, trackpad, and stylus) https://developer.android.com/docs/quality-guidelines/large-screen-app- quality#tier_3_basic_large_screen_ready 26
  16. 外部入力デバイスの基本サポート (Basic support for external input devices) キーボード (Keyboard) 外部キーボードを使用したテキスト入力に対応

    (Supports text input using external keyboard) 外部キーボードの接続・接続解除時にアプリの再起動不要 (No app relaunch required when external keyboard is connected or disconnected) 物理キーボードと仮想キーボードの自動切り替え (Automatic switching between physical and virtual keyboards) マウス・トラックパッド (Mouse, and trackpad) クリック・選択・スクロール (Click, Select, and Scroll) https://developer.android.com/docs/quality-guidelines/large-screen-app- quality#large_screen_ready 28
  17. TIER 2 (better) — Large screen optimized すべての画面サイズ・デバイス設定でレイアウトを最適化 (Layout optimizations

    for all screen sizes and device configurations) マルチウインドウモードを含む (Including multi-window mode) 外部入力デバイスのサポートを拡張 (Enhanced support for external input devices) https://developer.android.com/docs/quality-guidelines/large-screen-app- quality#tier_2_better_large_screen_optimized 29
  18. 外部入力デバイスのサポートを拡張 - キーボード (Enhanced support for external input devices -

    Keyboard) Tab・矢印キーによるキーボードナビゲーション対応 (Tab and arrow key navigation support) 選択、コピー&ペースト、元に戻すなどのキーボードショートカット対応 (Keyboard shortcuts for select, cut, copy, paste, undo, redo) Space キーでメディア再生・一時停止 (Spacebar plays and pauses media) Enter キーで送信機能実行 (Enter key performs send function in communication apps) https://developer.android.com/docs/quality-guidelines/large-screen-app-quality? hl=ja#large_screen_optimized 30
  19. 外部入力デバイスのサポートを拡張 - マウス、トラックパッド (Enhanced support for external input devices -

    Mouse, Trackpad) UI 要素のホバー状態表示 (Hover states for actionable UI elements) 右クリックでオプションメニュー表示 (Right-click accesses options menus) マウスホイール(Ctrl 併用) ・トラックパッドのピンチでズーム (Mouse scroll wheel (with Ctrl) and trackpad pinch for zoom) https://developer.android.com/docs/quality-guidelines/large-screen-app-quality? hl=ja#large_screen_optimized 31
  20. TIER 1 (best) — Large screen differentiated 大画面デバイス向けにデザインされたユーザーエクスペリエンスを提供 (Provides user

    experience designed for large screen devices) 該当する場合、追加機能のサポート (Where applicable, additional feature support) マルチタスク、フォルダブルデバイスの形状、ドラッグ&ドロップ、スタイラ ス入力 (Multitasking, Foldable postures, Drag and drop, Stylus input) https://developer.android.com/docs/quality-guidelines/large-screen-app- quality#tier_1_best_large_screen_differentiated 32
  21. Large screen differentiated App が提供する機能の例 (Example Features of Large Screen

    Differentiated Apps) Picture-in-picture Multiple instances Tabletop posture Dual display Drag and drop Draw and write within the app using a stylus https://developer.android.com/docs/quality-guidelines/large-screen-app- quality#large_screen_differentiated 33
  22. Android XR app quality guidelines Android XR compatible mobile app

    Android XR compatible large screen app Android XR differentiated app https://developer.android.com/docs/quality-guidelines/android-xr 35
  23. Large screen app quality TIER 1 or 2 == Android

    XR compatible large screen app 大画面対応のサポートレベル:TIER 2 Large screen optimized を達成すれば、Android XR への準備も(ある程度は)OK となる (Achieving TIER 2 Large screen optimized means your app is (mostly) ready for Android XR) https://developer.android.com/docs/quality-guidelines/android-xr#android-xr-compatible 36
  24. 重要な注意事項 (Important Notes) 本セッションでは、私個人が特に重要と感じた項目を中心に解説します (This session focuses on items I

    personally consider most important) 各 TIER の全ての要件を網羅しているわけではありません (Not covering all requirements for each TIER) 実際の認定には、公式ドキュメントで要件一覧を確認し、対応が必要です (For actual certification, check the full requirements list in Google's official documentation) 37
  25. 目次 (Agenda) 1. 大画面対応の重要性 (Importance of Large Screen Support) 2.

    大画面対応のサポートレベル (Large screen support levels) 3. View ベースアプリの大画面対応戦略 (Large Screen Strategy for View-based Apps) 4. 基本的な大画面対応 (Large screen ready) 5. 大画面向けに最適化 (Large screen optimized) 6. 更なる大画面対応 (Further Large Screen Support) 7. まとめ (Summary) 38
  26. View ベースアプリとは? (What are View-based Apps?) ほとんどの画面が View で構成されているアプリ (Apps

    mostly composed of View screens) 一部の画面は Compose に移行済みな場合もある (Some screens may already be migrated to Compose) 40
  27. 推奨アプローチ (Recommended Approach) 1. View ベースのまま、TIER 3 (basic) — Large

    screen ready 相当の大画面対応を行う (Implement TIER 3 large screen support while keeping View-based architecture) Android 16 での Behavior changes に対応する事を優先する (Prioritize addressing Android 16 behavior changes) Android 17 での opt-out 無効化まで、あまり時間は無い (Limited time until opt-out disabled in Android 17) 2. その後は 全画面の Compose 化に注力する (Then focus on migrating to Compose) 最終的には全画面を Compose 化 することを強く推奨 (We strongly recommend migrating all screens to Compose) 41
  28. Navigation 3 Navigation 3 で大画面に適したレイアウトを容易に実現 (Easy implementation of large screen

    layouts with Navigation 3) List-Detail 表示などを容易に実現 (Easy List-Detail implementation) Compose 専用ライブラリ (Navigation 3 is a Compose-only library) 44
  29. 目次 (Agenda) 1. 大画面対応の重要性 (Importance of Large Screen Support) 2.

    大画面対応のサポートレベル (Large screen support levels) 3. View ベースアプリの大画面対応戦略 (Large Screen Strategy for View-based Apps) 4. 基本的な大画面対応 (Large screen ready) 5. 大画面向けに最適化 (Large screen optimized) 6. 更なる大画面対応 (Further Large Screen Support) 7. まとめ (Summary) 45
  30. TIER 3 (basic) — Large screen ready 重要なタスクフローは完了可能 (Users can

    complete critical task flows) ユーザーエクスペリエンスは最適ではない (Less than optimal user experience) Configuration changes を適切に処理 (Handle configuration changes properly) 全画面で実行 (Full screen) レイアウトは理想的でない可能性あり (App layout might not be ideal) レターボックス表示なし (Not letterboxed) 外部入力デバイスの基本サポート (Basic support for external input devices) キーボード、マウス、トラックパッド、スタイラス (Keyboard, mouse, trackpad, and stylus) https://developer.android.com/docs/quality-guidelines/large-screen-app- quality#tier_3_basic_large_screen_ready 47
  31. 「基本的な大画面対応」の進め方 (Steps for Basic Large Screen Support) 1. アプリを全画面で実行する (Run

    app in full screen) 2. Configuration changes を適切に処理する (Handle configuration changes properly) 3. 重要なタスクフローを完了できるようにする (Enable critical task flows) 48
  32. 「基本的な大画面対応」の進め方 (Steps for Basic Large Screen Support) 1. アプリを全画面で実行する (Run

    app in full screen) 2. Configuration changes を適切に処理する (Handle configuration changes properly) 3. 重要なタスクフローを完了できるようにする (Enable critical task flows) 49
  33. 「基本的な大画面対応」の進め方 (Steps for Basic Large Screen Support) 1. アプリを全画面で実行する (Run

    app in full screen) 2. Configuration changes を適切に処理する (Handle configuration changes properly) 3. 重要なタスクフローを完了できるようにする (Enable critical task flows) 54
  34. 変更される構成の例 (Examples of Configuration Changes) アプリの表示サイズ (Display size) 画面の向き (Screen

    orientation) フォントのサイズと太さ (Font size and weight) 言語・地域 (Locale) ダークモード・ライトモード (Dark/Light mode) キーボードの有無 (Keyboard availability) 57
  35. デフォルトの動作 (Default Behavior) Configuration change が起きると Activity が再作成される (Activity is

    recreated when configuration changes occur) 結果 (Result) アプリ内部でのデータの持ち方次第で、アプリの様々な状態が失われる (Depending on how data is handled internally, various app states can be lost due to configuration changes) 59
  36. 失われるアプリ状態の例 (Examples of Lost App State) スクロール位置 (Scroll position) テキストやチェックボックスなどユーザーが入力した内容 (User

    input: text, checkboxes, etc.) メディア再生位置 (Media playback position) 表示中のダイアログ (Currently displayed dialogs) 画面遷移 (Screen navigation state) WebView の表示内容 (WebView content) 60
  37. Configuration changes 処理の基礎知識 (Fundamentals for Handling Configuration Changes) Activity が提供する状態保持の仕組み

    (Activity's state preservation mechanism) ViewModel SavedStateHandle View 固有の話 (View-specific topics) Compose 固有の話 (Compose-specific topics) 補足事項 (Additional notes) https://developer.android.com/topic/libraries/architecture/saving-states 61
  38. Activity#onSaveInstanceState override fun onSaveInstanceState(outState: Bundle?) { // Save the user's

    current game state. outState?.run { putInt(STATE_SCORE, currentScore) putInt(STATE_LEVEL, currentLevel) } // Always call the superclass so it can save the view hierarchy state. super.onSaveInstanceState(outState) } companion object { val STATE_SCORE = "playerScore" val STATE_LEVEL = "playerLevel" } https://developer.android.com/guide/components/activities/activity-lifecycle 63
  39. Activity#onRestoreInstanceState override fun onRestoreInstanceState(savedInstanceState: Bundle?) { // Always call the

    superclass so it can restore the view hierarchy. super.onRestoreInstanceState(savedInstanceState) // Restore state members from saved instance. savedInstanceState?.run { currentScore = getInt(STATE_SCORE) currentLevel = getInt(STATE_LEVEL) } } https://developer.android.com/guide/components/activities/activity-lifecycle 64
  40. Activity が提供する状態保持の仕組みの補足 (Additional Notes on Activity's State Preservation) 非常にシンプルな状態保持機能が提供されている (Provides

    very simple state preservation functionality) 近年の Android アプリ開発では、 (これから紹介する)より便利な方法が提供され ているので、そちらを使う事の方が多い (Modern Android development provides more convenient methods - introduced below - that are more commonly used) 便利な方法の一部は「Activity が提供する状態保持の仕組み」で実現している (Some of these convenient methods are built on top of Activity's state preservation mechanism) 65
  41. SavedStateHandle プロセス再作成時でも状態保持が可能 (Enables state preservation even during process recreation) class

    SavedStateViewModel( private val savedStateHandle: SavedStateHandle ) : ViewModel() { val filteredData: StateFlow<List<String>> = savedStateHandle.getStateFlow<String>("query") .flatMapLatest { query -> repository.getFilteredData(query) } fun setQuery(query: String) { savedStateHandle["query"] = query } } https://developer.android.com/topic/libraries/architecture/viewmodel/viewmodel- savedstate 67
  42. View 固有の話 (View-specific Topic) ID 指定すると状態が保持される (State is preserved when

    ID is specified) <EditText android:id="@+id/edit_text" // mandatory to save/restore state android:layout_width="match_parent" android:layout_height="wrap_content" /> https://developer.android.com/guide/fragments/saving-state#view 68
  43. Compose 固有の話 (Compose-specific Topics) rememberSavable で状態が保持される (State is preserved with

    rememberSavable) @Parcelize data class City(val name: String, val country: String) : Parcelable @Composable fun CityScreen() { var selectedCity = rememberSaveable { mutableStateOf(City("Madrid", "Spain")) } } 69
  44. About TransactionTooLargeException - 1/3 onSaveInstanceState で保存できるサイズには上限がある (There's a size limit

    for data saved in onSaveInstanceState) ↓ サイズ超過で TransactionTooLargeException が発生 (Exceeding the size limit causes TransactionTooLargeException) https://developer.android.com/guide/components/activities/parcelables-and-bundles 71
  45. About TransactionTooLargeException - 2/3 サイズ上限はアプリプロセス全体で1MB (Size limit is 1MB for

    the entire app process) SavedStateHandle, rememberSavable、AndroidX 一部ライブラリも同じ領域を使う (SavedStateHandle, rememberSavable, and some AndroidX libraries use the same storage area) アプリ側の保存サイズは 50KB 以下 が推奨 (App should keep saved data under 50KB) https://developer.android.com/guide/components/activities/parcelables-and-bundles 72
  46. About TransactionTooLargeException - 3/3 対策:ViewModel の活用、Room や DataStore などストレージでのデータ保持 (Solutions:

    Use ViewModel, persist data with Room or DataStore) https://developer.android.com/guide/components/activities/parcelables-and-bundles https://developer.android.com/topic/libraries/architecture/saving-states 73
  47. Activity の再作成制限について (About Activity Recreation Restriction) - 1/2 android:configChanges に

    Activity 再作成の制限対象を宣言できる (You can declare targets for Activity recreation restriction in android:configChanges ) <activity android:name=".MyActivity" android:configChanges="orientation|screenSize|screenLayout|keyboardHidden" android:label="@string/app_name"> https://developer.android.com/guide/topics/resources/runtime-changes#restrict-activity 74
  48. Activity の再作成制限について (About Activity Recreation Restriction) - 2/2 アプリ自体が Configuration

    changes を適切に処理する必要あり (App needs to handle configuration changes itself) View ベースアプリでは困難 (Difficult for View-based apps) 代替リソースは自動ロードされない (Alternative resources won't load automatically) 例: res/layout-sw600dp/ ではなく、常に res/layout/ が使われる (Example: Always uses res/layout/ instead of res/layout-sw600dp/ ) 75
  49. 「基本的な大画面対応」の進め方 (Steps for Basic Large Screen Support) 1. アプリを全画面で実行する (Run

    app in full screen) 2. Configuration changes を適切に処理する (Handle configuration changes properly) 3. 重要なタスクフローを完了できるようにする (Enable critical task flows) 76
  50. 1. 重要なタスクフローをリストアップ (List Critical Task Flows) U-NEXT アプリの場合 (For U-NEXT

    app): ログイン・会員登録 (Login & Registration) 購入・定期購入 (Purchase & Subscription) 作品を探す (Search for content) 動画を再生する (Play videos) 本を開く (Open books) 78
  51. 2. 問題を検出 (Detect all issues) 1. タブレットやフォルダブル端末で重要なタスクフローを実行 (Execute critical task

    flows on tablets and foldable devices) 2. タスクフロー完了が不可となる、クリティカルな問題を検出 (Detect critical issues that prevent task completion) 79
  52. 82

  53. Compose で縦スクロール可能にする (Enable Vertical Scrolling with Compose) Column( modifier =

    Modifier.verticalScroll(rememberScrollState()) ) { // content } LazyColumn() { // content } 84
  54. 86

  55. View で画像の Max 幅を制限する (Limit Image Max Width with View)

    <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView app:layout_constraintWidth_max="800dp" ... /> </androidx.constraintlayout.widget.ConstraintLayout> 87
  56. Compose で画像の Max 幅を制限する (Limit Image Max Width with Compose)

    Image( painter = painterResource(id = R.drawable.sample_image), contentDescription = "", modifier = Modifier .widthIn(max = 800.dp) // <- Set max width .fillMaxWidth() ) 88
  57. 89

  58. View で List item の Max 幅を制限する (Limit List Item

    Max Width with View) <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.recyclerview.widget.RecyclerView app:layout_constraintWidth_max="800dp" ... /> </androidx.constraintlayout.widget.ConstraintLayout> 90
  59. Compose で List item の Max 幅を制限する (Limit List Item

    Max Width with Compose) @Composable fun LimitedWidthLazyColumn() { LazyColumn( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, ) { items(20) { index -> ListItem( modifier = Modifier .widthIn(max = 800.dp) // <- Set max width .fillMaxWidth() ) { // content } } } } 91
  60. 92

  61. 目次 (Agenda) 1. 大画面対応の重要性 (Importance of Large Screen Support) 2.

    大画面対応のサポートレベル (Large screen support levels) 3. View ベースアプリの大画面対応戦略 (Large Screen Strategy for View-based Apps) 4. 基本的な大画面対応 (Large screen ready) 5. 大画面向けに最適化 (Large screen optimized) 6. 更なる大画面対応 (Further Large Screen Support) 7. まとめ (Summary) 93
  62. TIER 2 (better) — Large screen optimized すべての画面サイズ・デバイス設定でレイアウトを最適化 (Layout optimizations

    for all screen sizes and device configurations) マルチウインドウモードを含む (Including multi-window mode) 外部入力デバイスのサポートを拡張 (Enhanced support for external input devices) https://developer.android.com/docs/quality-guidelines/large-screen-app- quality#tier_2_better_large_screen_optimized 95
  63. レイアウトの最適化 (Layout Optimization) Window size classes Navigation rail の導入 (Implementing

    Navigation rail) リスト表示の改善 (Improving list displays) アプリごとに最適なレイアウトの検討 (Consider optimal layouts for your app) 96
  64. Window size class をブレークポイントとして、レイアウトを切り替える (Using Window Size Class as a

    Breakpoint for Layout Switching) @Composable fun MyApp( windowSizeClass: WindowSizeClass = currentWindowAdaptiveInfo().windowSizeClass ) { // Decide whether to show the top app bar based on window size class. val showTopAppBar = windowSizeClass .isHeightAtLeastBreakpoint(WindowSizeClass.HEIGHT_DP_MEDIUM_LOWER_BOUND) // MyScreen logic is based on the showTopAppBar boolean flag. MyScreen( showTopAppBar = showTopAppBar, /* ... */ ) } https://developer.android.com/develop/ui/compose/layouts/adaptive/use-window-size- classes#manage_layouts_with_window_size_classes 98
  65. どの Window size class でレイアウトを切り替えるか? (Which Window Size Class to

    Use for Layout Switching?) 1. Width window size class - isWidthAtLeastBreakpoint 2. Height window size class - isHeightAtLeastBreakpoint 3. Both window size classes - isAtLeastBreakpoint 99
  66. Navigation rail の導入 (Implementing Navigation Rail) ウインドウサイズに応じてナビゲーション UI の切替が推奨 (Recommended

    to switch navigation UI based on window size) 小さな画面では Navigation bar (Navigation bar for small screens) 大きな画面では Navigation rail (Navigation rail for large screens) 100
  67. NavigationSuiteScaffold( navigationSuiteItems = { AppDestinations.entries.forEach { item( icon = {

    Icon( it.icon, contentDescription = stringResource(it.contentDescription) ) }, label = { Text(stringResource(it.label)) }, selected = it == currentDestination, onClick = { currentDestination = it } ) } } ) { // Destination content } https://developer.android.com/develop/ui/compose/layouts/adaptive/build-adaptive- navigation 102
  68. リスト表示の改善 (Improving List Displays) LazyList -> LazyVerticalGrid ウインドウサイズで 1 行に表示するアイテム数調整

    (Adjust number of items per row based on window size) https://developer.android.com/develop/ui/compose/lists#la zy-grids 103
  69. GridCells.Fixed のコード例 - 1/2 val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass val columns

    = when { windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_EXPANDED_LOWER_BOUND) -> 3 windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_MEDIUM_LOWER_BOUND) -> 2 else -> 1 } 104
  70. GridCells.Fixed のコード例 - 2/2 LazyVerticalGrid( columns = GridCells.Fixed(columns), modifier =

    Modifier.fillMaxSize(), contentPadding = PaddingValues(12.dp), verticalArrangement = Arrangement.spacedBy(12.dp), horizontalArrangement = Arrangement.spacedBy(12.dp), ) { items(30) { Spacer( modifier = Modifier .background(MaterialTheme.colorScheme.primaryContainer) .aspectRatio(1f), ) } } 105
  71. 106

  72. GridCells.Adaptive のコード例 LazyVerticalGrid( columns = GridCells.Adaptive(minSize = 120.dp), modifier =

    Modifier.fillMaxSize(), contentPadding = PaddingValues(12.dp), verticalArrangement = Arrangement.spacedBy(12.dp), horizontalArrangement = Arrangement.spacedBy(12.dp), ) { items(30) { Spacer( modifier = Modifier .background(MaterialTheme.colorScheme.primaryContainer) .aspectRatio(1f), ) } } 107
  73. 108

  74. Large screens gallery Social media & communication Media Productivity Shopping

    Reading Creativity Games https://developer.android.com/large- screens/gallery 111
  75. Detail Pane から他の画面に遷移する場合、少し実装が複雑化する (Implementation becomes more complex when navigating to

    other screens from Detail Pane) 例:Detail Pane 専用の NavHost を追加 (Example: Add a dedicated NavHost for Detail Pane) Navigation 3 の正式リリースを待つのも選択肢の一つ (Waiting for Navigation 3's official release is also an option) 115
  76. 外部入力デバイスのサポートを拡張 (Extending External Input Device Support) キーボードナビゲーション (Keyboard navigation) Space

    キーでメディア再生・一時停止 (Space key for media play/pause) マウスホイールでのズーム (Mouse wheel zoom) 116
  77. キーボードナビゲーション (Keyboard Navigation) キーボード操作だけで主要なタスクフローを実行可能とする (Enable main task flows with keyboard

    only) Tab、矢印キーでフォーカス移動 (Focus navigation with Tab and arrow keys) 極力、矢印キーのみで完結するのが望ましい (Preferably complete with arrow keys only) Modifier.onClick で Enter にも反応する (Modifier.onClick responds to Enter key) 実際にキーボードだけで操作して問題点を洗い出してから改善 (Test with keyboard only to identify and fix issues) 117
  78. Modifier.focusProperties でフォーカス移動先を制御する (Control Focus Navigation with Modifier.focusProperties) val focusRequester =

    remember { FocusRequester() } Row { Button( onClick = {}, modifier = Modifier.weight(1f) .focusProperties { next = focusRequester // when Tab key pressed right = focusRequester // when Right arrow key pressed } ) { Text("1") } Button( onClick = {}, modifier = Modifier.weight(1f) .focusRequester(focusRequester) ) { Text("2") } } 118
  79. Modifier.onKeyEvent でスペースキー操作を処理する (Handle Space Key with Modifier.onKeyEvent) val focusRequester =

    remember { FocusRequester() } Surface( modifier = Modifier.focusRequester(focusRequester).focusable() .onKeyEvent { keyEvent -> when { keyEvent.type != KeyEventType.KeyDown -> false keyEvent.key == Key.Spacebar -> { // play / pause true } else -> false } }, ) { LaunchedEffect(Unit) { focusRequester.requestFocus() } Text("hello world") } 121
  80. 目次 (Agenda) 1. 大画面対応の重要性 (Importance of Large Screen Support) 2.

    大画面対応のサポートレベル (Large screen support levels) 3. View ベースアプリの大画面対応戦略 (Large Screen Strategy for View-based Apps) 4. 基本的な大画面対応 (Large screen ready) 5. 大画面向けに最適化 (Large screen optimized) 6. 更なる大画面対応 (Further Large Screen Support) 7. まとめ (Summary) 124
  81. TIER 1 (best) — Large screen differentiated 大画面デバイス向けにデザインされたユーザーエクスペリエンスを提供 (Provides user

    experience designed for large screen devices) 該当する場合、追加機能のサポート (Where applicable, additional feature support) マルチタスク、フォルダブルデバイスの形状、ドラッグ&ドロップ、スタイラ ス入力 (Multitasking, Foldable postures, Drag and drop, Stylus input) https://developer.android.com/docs/quality-guidelines/large-screen-app- quality#tier_1_best_large_screen_differentiated 126
  82. Large screen differentiated App が提供する機能の例 (Example Features of Large Screen

    Differentiated Apps) Picture-in-picture Multiple instances Tabletop posture Dual display Drag and drop Draw and write within the app using a stylus https://developer.android.com/docs/quality-guidelines/large-screen-app- quality#large_screen_differentiated 127
  83. Picture-in-Picture 小さなウインドウでアプリを利用可能 (App available in a small window) 主に動画の再生に使用 (Primarily

    used for video playback) Google Map アプリなど動画再生以外での使用例あり (Also used in non-video apps like Google Maps) Android 8.0 以上でサポート (Supported on Android 8.0+) https://developer.android.com/develop/ui/views/picture-in- picture 130
  84. Android 12 以上と 12 未満の両方で動作確認する (Test on both Android 12+

    and below) OS 側の実装が大きく変わった (OS implementation changed significantly) setAutoEnterEnabled を有効にするかどうかでも挙動が変わる (Behavior varies with setAutoEnterEnabled setting) 133
  85. Picture-in-Picture ウインドウ表示中はタッチイベントを受け取れない (App cannot receive touch events during PiP) ダイアログなど、ユーザーのタッチ操作が必須な

    UI 表示を避ける (Avoid UI that requires touch input like dialogs) 再生・停止などの操作は RemoteAction として定義 (Define play/stop controls as RemoteAction) 134
  86. Android 8.0 以上でもサポートしていない端末がある (Some devices don't support PiP even on

    Android 8.0+) hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) で判定 (Check with hasSystemFeature) ただし、一部端末は嘘を返すので、 activity.enterPictureInPictureMode は try catch しておくのが安全 (Some devices return false positives, so wrap enterPictureInPictureMode in try-catch) 135
  87. Picture-in-Picture ウインドウ表示中のアプリ起動ケースを考慮 (Consider app launch from launcher during PiP) SingleActivity

    化しないと、アプリ起動で自動 PiP 終了は実現不可 (Auto-exit PiP on app launch requires SingleActivity architecture) 136
  88. Tabletop posture フォルダブル端末メイン画面を半分程度開いた状態 (Foldable device's main screen half-opened) ユーザーが手でスマフォを持たなくて良い (Users

    don't need to hold the phone) メディア視聴や写真撮影・ビデオ通話に最適 (Ideal for media viewing, photography, and video calls) https://developer.android.com/develop/ui/compose/layouts /adaptive/foldables/make-your-app-fold-aware 138
  89. object TableTopModeTracker { fun isTableTop(context: Context): Flow<Boolean> { return WindowInfoTracker.getOrCreate(context)

    .windowLayoutInfo(context) .map { it.isTableTop } } } val WindowLayoutInfo.isTableTop: Boolean get() { val foldingFeature = displayFeatures .filterIsInstance<FoldingFeature>() .firstOrNull() ?: return false return foldingFeature.orientation == FoldingFeature.Orientation.HORIZONTAL && foldingFeature.state == FoldingFeature.State.HALF_OPENED } 139
  90. 目次 (Agenda) 1. 大画面対応の重要性 (Importance of Large Screen Support) 2.

    大画面対応のサポートレベル (Large screen support levels) 3. View ベースアプリの大画面対応戦略 (Large Screen Strategy for View-based Apps) 4. 基本的な大画面対応 (Large screen ready) 5. 大画面向けに最適化 (Large screen optimized) 6. 更なる大画面対応 (Further Large Screen Support) 7. まとめ (Summary) 141
  91. 大画面対応は待ったなし (Large Screen Support Can't Wait) 2025 Target SDK 36

    で 画面回転・アスペクト比制限が無視される (Orientation and aspect ratio restrictions ignored for API level 36) 2026 Target SDK 37 で opt-out 不可 (No opt-out for API level 37) 今すぐ対応を始めましょう! (Start adapting now!) 143
  92. Step 1: TIER 3 対応 - View でも可能 (TIER 3

    Support - Possible with View) 全画面実行 (Full screen execution) Configuration changes 処理 (Handle configuration changes) スクロール対応と Max 幅制限 (Scrolling and max width constraints) 145
  93. Step 2: TIER 2 以上を目指して大画面に最適化 (Step 2: Optimize for Large

    Screens Targeting TIER 2+) 柔軟なレイアウト対応 (Flexible layout support) キーボード・マウス対応 (Keyboard and mouse support) 146
  94. Large screen app quality と Android XR の関係 (Relationship between

    Large screen app quality and Android XR) TIER 2 達成 = Android XR compatible large screen app 大画面対応は XR 対応の第一歩 (Large screen support is the first step to XR) Android XR デバイスでも快適に動作するアプリに (Apps that work on Android XR devices) より多くのユーザーにリーチ (Reach more users) 148
  95. 今日から試せること (What You Can Try Today) 1. AndroidManifest.xml の変更 (Modify

    AndroidManifest.xml) 画面向き指定の削除 (Remove orientation specification) アスペクト比指定の削除 (Remove aspect ratio specification) リサイズ制限の削除 (Remove resizeable restriction) 2. 大画面デバイスでの動作確認 (Test on large screen devices) 横画面でのレイアウト確認 (Check layout in landscape mode) デバイスを回転させてテスト (Rotate device and test) 画面分割でテスト (Test with split screen) 149
  96. リソース (Resources) 公式ドキュメント (Official Documentation) Large screen app quality guidelines

    Android 16 behavior changes Window Size Classes 公式サンプルコード (Official Sample Code) Now in Android - Canonical layouts の実装例 Compose samples - Adaptive layouts 151