Android TV でのカスタムビューのユーザー補助サポート

多くの Android TV アプリはネイティブ Android コンポーネントで構築されていますが、特にカスタムビューを使用する場合は、サードパーティのフレームワークまたはコンポーネントのユーザー補助機能を考慮することも重要です。

OpenGL や Canvas と直接やり取りするカスタムビュー コンポーネントは、TalkBack やスイッチ アクセスなどのユーザー補助サービスでは適切に動作しない場合があります。

TalkBack をオンにすると、次のような問題が発生する可能性があります。

  • アプリでユーザー補助フォーカス(緑色の長方形)が消えることがあります。
  • ユーザー補助機能のフォーカスで画面全体の境界が選択される場合もあります。
  • ユーザー補助フォーカスが移動できない場合があります。
  • D-pad の 4 つの方向キーは、コードで処理しても効果がない場合があります。

アプリで上記の問題が見られた場合は、その AccessibilityNodeInfo ツリーがユーザー補助サービスに公開されていることをご確認ください。

これ以降は、これらの問題に対処するためのソリューションとベスト プラクティスをいくつか紹介します。

D-pad イベントがユーザー補助サービスで使用される

この問題の根本原因は、キーイベントがユーザー補助サービスで使用されていることです。

D-pad イベントの使用 図 1. TalkBack のオン / オフでのシステムの動作を表す図。

図 1 に示すように、TalkBack がオンになっている場合、デベロッパーが定義した D-pad ハンドラに D-pad イベントは渡されません。代わりに、ユーザー補助サービスはキーイベントを受信して、ユーザー補助フォーカスを移動します。カスタム Android コンポーネントは、デフォルトでは画面上の位置に関する情報をユーザー補助サービスに公開しないため、ユーザー補助サービスがユーザー補助のフォーカスを移動してハイライト表示することはできません。

他のユーザー補助サービスも同様に影響を受けます。スイッチ アクセスの使用時に、D-pad イベントが使用される可能性があります。

D-pad イベントはユーザー補助サービスに送信されますが、このサービスでは UI コンポーネントがカスタムビュー内のどこにあるかわからないため、アプリでキーイベントを正しく転送するには AccessibilityNodeInfo を実装する必要があります。

ユーザー補助サービスに情報を公開する

カスタムビューの場所と説明に関する十分な情報をユーザー補助サービスに提供するには、AccessibilityNodeInfo を実装して各コンポーネントの詳細を公開します。ユーザー補助サービスがフォーカスを管理できるようにビューの論理関係を定義するには、ExploreByTouchHelper を実装し、カスタムビューに ViewCompat.setAccessibilityDelegate(View, AccessibilityDelegateCompat) を使用して設定します。

ExploreByTouchHelper を実装する場合は、次の 4 つの抽象メソッドをオーバーライドします。

Kotlin

// Return the virtual view ID whose view is covered by the input point (x, y).
protected fun getVirtualViewAt(x: Float, y: Float): Int

// Fill the virtual view ID list into the input parameter virtualViewIds.
protected fun getVisibleVirtualViews(virtualViewIds: List<Int>)

// For the view whose virtualViewId is the input virtualViewId, populate the
// accessibility node information into the AccessibilityNodeInfoCompat parameter.
protected fun onPopulateNodeForVirtualView(virtualViewId: Int, @NonNull node: AccessibilityNodeInfoCompat)

// Set the accessibility handling when perform action.
protected fun onPerformActionForVirtualView(virtualViewId: Int, action: Int, @Nullable arguments: Bundle): Boolean

Java

// Return the virtual view ID whose view is covered by the input point (x, y).
protected int getVirtualViewAt(float x, float y)

// Fill the virtual view ID list into the input parameter virtualViewIds.
protected void getVisibleVirtualViews(List<Integer> virtualViewIds)

// For the view whose virtualViewId is the input virtualViewId, populate the
// accessibility node information into the AccessibilityNodeInfoCompat parameter.
protected void onPopulateNodeForVirtualView(int virtualViewId, @NonNull AccessibilityNodeInfoCompat node)

// Set the accessibility handling when perform action.
protected boolean onPerformActionForVirtualView(int virtualViewId, int action, @Nullable Bundle arguments)

詳しくは、Google I/O 2013 - 目の不自由な方やロービジョンのユーザー補助機能を Android で有効にするをご覧になるか、ユーザー補助イベントの入力をご覧ください。

ベスト プラクティス

サンプル

カスタムビューを使用するアプリにユーザー補助サポートを追加するためのおすすめの方法については、Android TV 用のカスタムビューのユーザー補助のサンプルをご覧ください。