Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
縦横無尽に駆け回るフォーカスをユーザーフレンドリーに制御する feat. Compose fo...
Search
Daichi Takeya
May 30, 2025
Programming
100
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
縦横無尽に駆け回るフォーカスをユーザーフレンドリーに制御する feat. Compose for TV
2025/05/30 CA.aab #6の登壇資料です
Daichi Takeya
May 30, 2025
More Decks by Daichi Takeya
See All by Daichi Takeya
Worry free TV App development for users and developers - a focus on Compose internal implementation
taked137
0
34
ユーザーも開発者も悩ませない TV アプリ開発 ~Compose の内部実装から学ぶフォーカス制御~
taked137
0
480
Other Decks in Programming
See All in Programming
Contextとはなにか
chiroruxx
0
200
決定論的オーケストレーションの設計と実装 / Design and Implementation of Deterministic Orchestration
nrslib
3
1.2k
AI 時代のソフトウェア設計の学び方
masuda220
PRO
29
12k
Swiftのレキシカルスコープ管理
kntkymt
0
220
tsserverとは何だったのか、これからどうなるのか
nowaki28
1
460
TAKTでAI駆動開発の品質を設計する
j5ik2o
6
1.1k
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.3k
OSもどきOS
arkw
0
470
Dataformのリポジトリを立ち上げるときにまずやること / dataform-day0-2026
snhryt
0
130
Language Server 使ってる? 〜VSCode と Zed の場合〜 / Are you using a Language Server? ~For VS Code and Zed~
handlename
0
770
AI駆動開発で崩れていくコードベースを立て直す
kyoko_nr_nr
1
450
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
0
170
Featured
See All Featured
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
The Art of Programming - Codeland 2020
erikaheidi
57
14k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.4k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.5k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4k
Deep Space Network (abreviated)
tonyrice
0
170
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
860
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.5k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
580
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
410
Transcript
縦横無尽に駆け回るフォーカスを ユーザーフレンドリーに制御する feat. Compose for TV CA.aab #6 - 2025/05/30
Daichi Takeya
自己紹介 • Daichi Takeya ◦ X:@taked_oO ◦ GitHub:@taked137 • 株式会社AbemaTV
• Android-based TV向けのABEMAアプリを作っています 2
• リモコンを利用した操作 TV アプリの操作 "TV Navigation Controller" by Android Developers,
licensed under CC BY 2.5. ・フォーカスされている Itemを目立たせる ・フォーカスに伴って 自動でスクロール する Mobile アプリほど直感的な操作が行えない フォーカスの操作性 がユーザー体験に大きく関係する
• フォーカスに伴う処理をよしなに行う Android View ベースのライブラリ Leanback ライブラリ 命令的にUI描画を行うので意図せぬ状態の更新漏れが生じやすい 2025年にもなって Adapter
を触りたくない 😤😤😤 RecyclerView Leanback とは言え、、、 フォーカス体験を向上 させる ロジックが既に実装されている
• Compose for TV は二つのライブラリが存在 ◦ tv-material (stableになった🎉) ◦ tv-foundation
(stable な “compose-foundation” にマイグレーション🚛) Leanback から Compose for TV への移行 Leanback Compose フォーカス目立ちにくいし 縦移動時に謎の横スクロールが 生じてるよ 自分でなんとかする必要があります \ナンテコッタイ / 今回の対象 Compose for TV の時代が来た!?
Compose におけるデフォルトのフォーカス移動 • 入力したキー方向で一番近い View がフォーカスされる 実際のフォーカス移動 キー方向に対応するフォーカス先 シンプルな画面だと デフォルトの挙動で十分
💯 みんな幸せ
デフォルトのフォーカス移動に関するクイズ Q. ピンクのアイテム上で “←” を押下すると、次は何がフォーカスされる?
デフォルトのフォーカス移動に関するクイズ Q. ピンクのアイテム上で “←” を押下すると、次は何がフォーカスされる? ワタシだ
デフォルトのフォーカス制御ロジックの深掘り フォーカス中の View よりも “左側” にあり “右側” にはみ出ていないことが 選出条件 ❌
❌ ❌ • なぜ “←” 押下で、一番左上のアイテム (“Title 1”) にフォーカスが当たるのか 他の View は “左右” というよりは “上下” に位置していると感じられる👏 フォーカス中の View と “Y座標” が重なっていると 優先的に選出 ⭕ ⭕ ⭕
デフォルトのフォーカス制御ロジックの深掘り フォーカス中の View よりも “左側” にあり “右側” にはみ出ていないことが 選出条件 ❌
❌ ❌ • なぜ “←” 押下で、一番左上のアイテム (“Title 1”) にフォーカスが当たるのか 他の View は “左右” というよりは “上下” に位置していると感じられる👏 フォーカス中の View と “Y座標” が重なっていると 優先的に選出 ⭕ ⭕ ⭕ この他にも多くの精巧なロジックによって フォーカス制御が行われている
デフォルトのフォーカス制御の限界 • 純粋に View の位置関係だけに基づいたフォーカス移動 ◦ Column や Row といった
Component の単位を考慮していない 右側のリストの 初期フォーカスが 先頭のアイテムに当たらない 左側のリストに戻った時 同じアイテムが選択されない Master/Detail Flow な画面
フォーカス位置の保存/復元 • “フォーカス位置の復元 ” が自然なUXを実現するための大事な要素 Compose ではフォーカス位置の復元ロジックを別途実装する必要あり Viewの位置関係だけに基づいたフォーカス移動 😚 左右にある前後のタブへ自然に移動できる
😒 何の脈略もないタブへ急に移動する フォーカス位置を復元
Modifier.focusRestorer • フォーカス位置の保存/復元をよしなに実行してくれる ・Modifier に追加するだけで良い ・compose-ui 1.8.0 にて遂に stable に
Modifier.focusRestorer を適用した後の挙動 左右の Column それぞれに focusRestorer を設定 フォーカス位置が 復元される👍 右側のリストが更新されても
以前のフォーカス対象が 復元されてしまう 😑
• focusRestorer の状態を初期化したい ◦ compose.runtime.key を使用 (⚠パフォーマンスとのトレードオフあり ) 明示的なコンポジションの再生成 左側の別のタブが選択されたら コンポジションを再生成
右側のリスト更新に伴って focusRestorer の状態も 初期化される👍 focusRestorer 初期化直後の フォーカス対象の選出は 位置ベースで実行される 😑 あと一息、、、!
focusRestorer の fallback 対象を指定 • 初回などといったフォーカス対象の復元に失敗した際の fallback 先を指定 復元するフォーカス対象が無い場合は 右側のリストの先頭にフォーカス
フォーカス対象を 識別するためのマーカー 見失わないフォーカスに 🎉 focusRestorer 初期化後は View の位置関係を利用した探索はせず 先頭の要素にフォーカスする
focusRestorer の fallback 対象を指定 • 初回などといったフォーカス対象の復元に失敗した際の fallback 先を指定 復元するフォーカス対象が無い場合は 右側のリストの先頭にフォーカス
フォーカス対象を 識別するためのマーカー 見失わないフォーカスに 🎉 focusRestorer 初期化後は View の位置関係を利用した探索はせず 先頭の要素にフォーカスする フォーカス対象の復元以外にも もっと柔軟なフォーカス制御を行いたい!
FocusRequester • 特定の Composable に対してフォーカスをリクエストする API ◦ 🚨 Modifier.focusRequester で
Composable に attach していないとクラッシュ する ▪ compose-ui 1.9.0-alpha01 で Exception の throw から println での警告に変更 focusRestorer の fallback 先に指定 フォーカス当てたり外したり 分割代入で一括生成も可能 Composable に attach した FocusRequester を用いてフォーカス制御を行う
focusProperties による柔軟なフォーカス制御 🔵Row (focusGroup) の初期フォーカスは My Button 2 🔴右キーで My
Button 2 にフォーカス 🟡左キーはデフォルトのフォーカス先 🟢下キーを押してもフォーカス移動はしない FocusRequester を用いて、次のフォーカス先を明示
focusProperties の注意点 focusProperties で 実現してみる フォーカス制御ロジックが 支配的となり 可読性・保守性が著しく低下する コード量が約 2倍に
😫 focusProperties を使えば (おそらく) 全てのユースケースに 対応できる トレードオフを意識しながら 使用する API を検討しよう 💪
Compose for TV の最近のアップデート 2025/05/19時点 compose-ui 1.8.2 🎉 focusRestorer や
focusProperties が stable に 🎉 ↑ に伴って、いくつかのクラッシュが解消 🚨 スクロールアニメーションが spring() に固定化 stable compose-ui 1.9.0-alpha02 ℹFocusRequester を attach し忘れて利用しても Exception が投げられないようになる (println での警告) 🫣スクロールアニメーション問題修正してほしい (Issue Tracker には別の方が起票済み ) alpha Android-based TV アプリの 更なる進化にご期待ください アプデ速度も早くなってきた印象 今後も Compose for TV の進化から目が離せない!
まとめ • TV アプリはフォーカス操作の快適さがユーザー体験に大きく影響 ◦ Leanback ライブラリは体験が向上するための工夫をよしなに実現してくれていた ◦ Compose for
TV では自前で実装していく必要がある • フォーカス制御を行う API はいくつかある ◦ FocusRequester, focusProperties, focusRestorer, etc… ▪ 可読性・アプリパフォーマンス・エラー耐性などのトレードオフを 考慮しながら使い分けていこう