一部の Wear OS デバイスはロータリー入力(回転サイドボタン(RSB)など)をサポートしています。ユーザーがボタンを回すと、アプリの現在のビューが上または下にスクロールします。
アプリ内で ScrollView、ListView、HorizontalScrollView、WearableRecyclerView のいずれかを使用している場合、アプリのビューはデフォルトでロータリー入力をサポートします。上記以外のカスタムビューを使用している場合や、ロータリー入力イベントを手動で処理する必要がある場合は、カスタムのロータリー入力スクロールを追加するをご覧ください。
以下の関連リソースをご覧ください。
フォーカスに関するおすすめの方法
ロータリー入力イベントに応答するには、スクロール ビューがフォーカスされている必要があります。ほとんどの場合、これは自動的に行われます。Activity を作成するとすぐに、スクロール ビューがフォーカスされます。ただし、以下のような状況では、アプリのビューのフォーカスを手動で処理する必要があります。
- Activity.onCreate() の後にスクロール可能なビューがアタッチされる場合(たとえば、UI を構築する前にネットワーク リクエストが終了するのを待機する場合)は、ビューがアタッチされた後で requestFocus を呼び出す必要があります。
- スクロール可能なビューが最初は INVISIBLE または GONE である場合、VISIBLE に設定する際に
requestFocus
を呼び出す必要があります。 - アクティビティにスクロール可能なビューが複数含まれている場合(たとえば、ネストされたスクロールを使用している場合)は、1 つのビューを選択する必要があります(通常は <requestFocus /> タグで選択します)。現在、RSB のスクロールでは、ネストされたスクロールはサポートされていません。
- ユーザーが操作したときにフォーカスを奪うビューが UI に含まれている場合(まれなケースですが、最も一般的な例は
InputText
です)、スクロール可能なビューがフォーカスを失ったときにフォーカスを取り戻すなんらかの方法をユーザーに提供する必要があります。そのための方法として、通常はスクロール可能なビューのタップをリッスンし、タップされたときにrequestFocus
を呼び出します。
カスタムのロータリー入力スクロールを追加する
スクロール可能なビューがロータリー入力スクロールをネイティブにサポートしていない場合、またはロータリー入力イベント(拡大 / 縮小、ダイヤルを回すなど)に応じてスクロール以外の動作を行う必要がある場合は、ウェアラブル サポート ライブラリの RotaryEncoder
メソッドを使用できます。
次のコード スニペットは、RotaryEncoder
を使用してカスタム スクロールをアプリのビューに追加する方法を示しています。
Kotlin
myView.setOnGenericMotionListener(View.OnGenericMotionListener { v, ev -> if (ev.action == MotionEvent.ACTION_SCROLL && RotaryEncoder.isFromRotaryEncoder(ev)) { // Don't forget the negation here val delta = -RotaryEncoder.getRotaryAxisValue(ev) * RotaryEncoder.getScaledScrollFactor(context) // Swap these axes if you want to do horizontal scrolling instead v.scrollBy(0, Math.round(delta)) return@OnGenericMotionListener true } false })
Java
myView.setOnGenericMotionListener(new View.OnGenericMotionListener() { @Override public boolean onGenericMotion(View v, MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_SCROLL && RotaryEncoder.isFromRotaryEncoder(ev)) { // Don't forget the negation here float delta = -RotaryEncoder.getRotaryAxisValue(ev) * RotaryEncoder.getScaledScrollFactor( getContext()); // Swap these axes if you want to do horizontal scrolling instead v.scrollBy(0, Math.round(delta)); return true; } return false; } });
エミュレータでロータリー入力ボタンをテストする
Android Emulator を使用すると、Wear デバイスでロータリー入力スクロールをシミュレートできます。そのためには、プロジェクトを実行するときにエミュレータで Wear アプリを起動するか、APK ファイルをエミュレータにドラッグしてインストールします。
エミュレータでロータリー入力をテストする手順は次のとおりです。
- SDK Manager の [SDK tools] タブで、Android Emulator 26.0.3 以上を入手します。
- API 25 を使用して AVD(Android Virtual Device)を作成します。
Studio で、[Tools] > [Android] > [AVD Manager] を選択します。 API 25 を使用して新しい Wear デバイスを作成します。
- Android Studio からエミュレータを実行します。
- ロータリー入力スクロールを試します。
オーバーフロー ボタン(エミュレータ ツールバーの下部にある 3 つの点)をクリックします。次に、新しいウィンドウで [Rotary input] タブをクリックして、ロータリー入力インターフェースを開きます。
次の動画は、エミュレータでのロータリー入力を示しています。
フォーカスの動作に関するヒント
- Android 9(API レベル 28)以降では、ビューは暗黙的にフォーカスを受け取らないため、明示的にフォーカスを受け取る必要があります。
- スクロール可能なビューは、
android:focusable="true"
とandroid:focusableInTouchMode="true"
の両方を使用して、フォーカス可能なビューとして登録する必要があります。 - デフォルトでは、アクティビティを起動しても、またはビューをタップしても、ビューは(フォーカス可能であっても)フォーカスされません。ビューがフォーカスされるようにするには、ビューで
<requestFocus />
タグを使用するか、または手動でView.requestFocus()
を呼び出す必要があります。 - ロータリー入力イベントは、フォーカスされているビューにのみ送信されます。このイベントによってビュー階層が上に移動することはありません。フォーカスされているビューがない場合、またはフォーカスされているビューが
View.onGenericMotionEvent
からfalse
を返す場合にのみ、イベントはActivity.onGenericMotionEvent
に送信されます。