トランスポート コントロールを使用する

Compose でビルドを改善する
Android TV OS 用の Jetpack Compose を使用して、最小限のコードで美しい UI を作成します。
<ph type="x-smartling-placeholder"></ph> テレビ向け Compose →

Leanback UI ツールキットの再生コントロールにより、 向上させることができます動画アプリの場合は、トランスポート コントロールで動画のスクラブがサポートされます 早送りと巻き戻しの操作を行いますディスプレイをスクラブすると、 動画内を移動しやすくします。

このライブラリには、抽象クラスと、事前構築済みのすぐに使える実装が含まれている より細かく制御できるようになります。事前ビルド済みの 実装すると、多くのコーディングを行うことなく、機能豊富なアプリをすばやく構築できます。 さらにカスタマイズが必要な場合は、ライブラリのビルド済みライブラリを拡張できます。 説明します。

コントロールとプレーヤー

Leanback UI ツールキットでは、トランスポート コントロールの UI を 動画を再生するプレーヤーです。これは、次の 2 つのコンポーネントによって実現されます。 トランスポート コントロールを表示するための再生サポート フラグメント プレーヤー アダプターを使用してメディア プレーヤーをカプセル化します。

再生フラグメント

アプリの UI アクティビティでは、 PlaybackSupportFragment または VideoSupportFragment。 そのどちらにも Leanback トランスポート コントロールが含まれています。

  • PlaybackSupportFragment は、トランスポート コントロールをアニメーション化し、必要に応じて表示 / 非表示を切り替えます。
  • VideoSupportFragmentPlaybackSupportFragment を拡張したもので、動画をレンダリングする SurfaceView を備えています。

フラグメントの ObjectAdapter UI を強化します。たとえば、 setAdapter() [関連動画]を追加します選択します。

PlayerAdapter

PlayerAdapter は、Pod を 基盤となるメディア プレーヤーを制御します。デベロッパーは ビルド済みの MediaPlayerAdapter 実装を使用するか、 実装するために使用できます。

フラグメントを接着する

「制御用接着剤」という使用して再生フラグメントを接続する 渡します。レインバック ライブラリには次の 2 種類の接着剤が用意されています。

  • PlaybackBannerControlGlue は、 「以前のスタイル」の再生フラグメントのトランスポート コントロールを 背景の中に表示されます。(PlaybackBannerControlGlue PlaybackControlGlue に代わるものです。 推奨されません)。
  • PlaybackTransportControlGlue 「新しいスタイル」を使用背景が透明です。

Leanback トランスポート コントロール用接着剤

アプリで動画スクラブをサポートするには、 PlaybackTransportControlGlue

また、「グルーホスト」も指定する必要があります。 再生に接着剤をバインドします。 フラグメントは、UI にトランスポート コントロールを描画し、その状態を維持します。 トランスポート コントロール イベントを接着剤に渡します。ホストは、再生フラグメントのタイプに適合する必要があります。使用 PlaybackSupportFragmentGlueHostPlaybackFragment VideoSupportFragmentGlueHost: VideoFragment

この図は、Leanback トランスポート コントロールの各要素を示しています。 組み合わせる:

Leanback トランスポート コントロール用接着剤

アプリを接着するコードは、コードの UI を定義する PlaybackSupportFragment または VideoSupportFragment

実際に たとえば、アプリは PlaybackTransportControlGlue のインスタンスを作成します。 名前は playerGlue とします。 そして、その VideoSupportFragment を新しく作成された MediaPlayerAdapter に接続します。以降 これは VideoSupportFragment です。セットアップ コードが setHost() を呼び出して、 VideoSupportFragmentGlueHost から playerGlue に変更。このコードはクラス内に含まれています。 VideoSupportFragment を拡張します。

Kotlin

class MyVideoFragment : VideoSupportFragment() {

  fun onCreate(savedInstanceState: Bundle) {
      super.onCreate(savedInstanceState)
      val playerGlue = PlaybackTransportControlGlue(getActivity(),
          MediaPlayerAdapter(getActivity()))
      playerGlue.setHost(VideoSupportFragmentGlueHost(this))
      playerGlue.addPlayerCallback(object : PlaybackGlue.PlayerCallback() {
          override fun onPreparedStateChanged(glue: PlaybackGlue) {
              if (glue.isPrepared()) {
                  playerGlue.seekProvider = MySeekProvider()
                  playerGlue.play()
              }
          }
      })
      playerGlue.setSubtitle("Leanback artist")
      playerGlue.setTitle("Leanback team at work")
      val uriPath = "android.resource://com.example.android.leanback/raw/video"
      playerGlue.getPlayerAdapter().setDataSource(Uri.parse(uriPath))
  }
}

Java

public class MyVideoFragment extends VideoSupportFragment {

  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      final PlaybackTransportControlGlue<MediaPlayerAdapter> playerGlue =
              new PlaybackTransportControlGlue(getActivity(),
                      new MediaPlayerAdapter(getActivity()));
      playerGlue.setHost(new VideoSupportFragmentGlueHost(this));
      playerGlue.addPlayerCallback(new PlaybackGlue.PlayerCallback() {
          @Override
          public void onPreparedStateChanged(PlaybackGlue glue) {
              if (glue.isPrepared()) {
                  playerGlue.setSeekProvider(new MySeekProvider());
                  playerGlue.play();
              }
          }
      });
      playerGlue.setSubtitle("Leanback artist");
      playerGlue.setTitle("Leanback team at work");
      String uriPath = "android.resource://com.example.android.leanback/raw/video";
      playerGlue.getPlayerAdapter().setDataSource(Uri.parse(uriPath));
  }
}

なお、このセットアップ コードでは、イベントを処理する PlayerAdapter.Callback も定義しています。 クリックします。

UI 用接着剤をカスタマイズする

カスタマイズ可能 PlaybackBannerControlGluePlaybackTransportControlGlue 変更して PlaybackControlsRow

タイトルと説明をカスタマイズする

上部のタイトルと説明をカスタマイズするには、 再生コントロール、オーバーライド onCreateRowPresenter():

Kotlin

override fun onCreateRowPresenter(): PlaybackRowPresenter {
    return super.onCreateRowPresenter().apply {
        (this as? PlaybackTransportRowPresenter)
                ?.setDescriptionPresenter(MyCustomDescriptionPresenter())
    }
}

Java

@Override
protected PlaybackRowPresenter onCreateRowPresenter() {
  PlaybackTransportRowPresenter presenter = (PlaybackTransportRowPresenter) super.onCreateRowPresenter();
  presenter.setDescriptionPresenter(new MyCustomDescriptionPresenter());
  return presenter;
}

コントロールを追加する

コントロール用接着剤は、PlaybackControlsRow 内のアクションのコントロールを表示します。

PlaybackControlsRow でのアクション は、プライマリ アクションセカンダリ アクションの 2 つのグループに割り当てられます アクション。プライマリ グループのコントロールはシークバーの上に、 セカンダリ グループがシークバーの下に表示されます。最初はメインのアクションは 1 つのみです。 サブアクションはありません。

次のようにオーバーライドすることで、プライマリ グループとセカンダリ グループにアクションを追加できます。 onCreatePrimaryActions()onCreateSecondaryActions()

Kotlin

private lateinit var repeatAction: PlaybackControlsRow.RepeatAction
private lateinit var pipAction: PlaybackControlsRow.PictureInPictureAction
private lateinit var thumbsUpAction: PlaybackControlsRow.ThumbsUpAction
private lateinit var thumbsDownAction: PlaybackControlsRow.ThumbsDownAction
private lateinit var skipPreviousAction: PlaybackControlsRow.SkipPreviousAction
private lateinit var skipNextAction: PlaybackControlsRow.SkipNextAction
private lateinit var fastForwardAction: PlaybackControlsRow.FastForwardAction
private lateinit var rewindAction: PlaybackControlsRow.RewindAction

override fun onCreatePrimaryActions(primaryActionsAdapter: ArrayObjectAdapter) {
    // Order matters, super.onCreatePrimaryActions() will create the play / pause action.
    // Will display as follows:
    // play/pause, previous, rewind, fast forward, next
    //   > /||      |<        <<        >>         >|
    super.onCreatePrimaryActions(primaryActionsAdapter)
    primaryActionsAdapter.apply {
        add(skipPreviousAction)
        add(rewindAction)
        add(fastForwardAction)
        add(skipNextAction)
    }
}

override fun onCreateSecondaryActions(adapter: ArrayObjectAdapter?) {
    super.onCreateSecondaryActions(adapter)
    adapter?.apply {
        add(thumbsDownAction)
        add(thumbsUpAction)
    }
}

Java

private PlaybackControlsRow.RepeatAction repeatAction;
private PlaybackControlsRow.PictureInPictureAction pipAction;
private PlaybackControlsRow.ThumbsUpAction thumbsUpAction;
private PlaybackControlsRow.ThumbsDownAction thumbsDownAction;
private PlaybackControlsRow.SkipPreviousAction skipPreviousAction;
private PlaybackControlsRow.SkipNextAction skipNextAction;
private PlaybackControlsRow.FastForwardAction fastForwardAction;
private PlaybackControlsRow.RewindAction rewindAction;

@Override
protected void onCreatePrimaryActions(ArrayObjectAdapter primaryActionsAdapter) {
    // Order matters, super.onCreatePrimaryActions() will create the play / pause action.
    // Will display as follows:
    // play/pause, previous, rewind, fast forward, next
    //   > /||      |<        <<        >>         >|
    super.onCreatePrimaryActions(primaryActionsAdapter);
    primaryActionsAdapter.add(skipPreviousAction);
    primaryActionsAdapter.add(rewindAction);
    primaryActionsAdapter.add(fastForwardAction);
    primaryActionsAdapter.add(skipNextAction);
}

@Override
protected void onCreateSecondaryActions(ArrayObjectAdapter adapter) {
    super.onCreateSecondaryActions(adapter);
    adapter.add(thumbsDownAction);
    adapter.add(thumbsUpAction);
}

オーバーライドする必要があります onActionClicked(): 新しいアクションを処理します。

Kotlin

override fun onActionClicked(action: Action) {
    when(action) {
        rewindAction -> {
            // Handle Rewind
        }
        fastForwardAction -> {
            // Handle FastForward
        }
        thumbsDownAction -> {
            // Handle ThumbsDown
        }
        thumbsUpAction -> {
            // Handle ThumbsUp
        }
        else ->
            // The superclass handles play/pause and delegates next/previous actions to abstract methods,
            // so those two methods should be overridden rather than handling the actions here.
            super.onActionClicked(action)
    }
}

override fun next() {
    // Skip to next item in playlist.
}

override fun previous() {
    // Skip to previous item in playlist.
}

Java

@Override
public void onActionClicked(Action action) {
    if (action == rewindAction) {
        // Handle Rewind
    } else if (action == fastForwardAction ) {
        // Handle FastForward
    } else if (action == thumbsDownAction) {
        // Handle ThumbsDown
    } else if (action == thumbsUpAction) {
        // Handle ThumbsUp
    } else {
        // The superclass handles play/pause and delegates next/previous actions to abstract methods,
        // so those two methods should be overridden rather than handling the actions here.
        super.onActionClicked(action);
    }
}

@Override
public void next() {
    // Skip to next item in playlist.
}

@Override
public void previous() {
    // Skip to previous item in playlist.
}

特殊なケースでは、独自のインターフェースを実装して PlaybackTransportRowPresenter カスタム コントロールをレンダリングし、 PlaybackSeekUi

動画スクラブ

アプリで VideoSupportFragment を使用している場合は、動画スクラブをサポートすることをおすすめします。

スクラブ

マイページ PlaybackSeekDataProvider の実装を提供する必要があります。 このコンポーネントでは、スクロール時に使用する動画のサムネイルが提供されます。 独自のプロバイダを実装するために、 PlaybackSeekDataProvider。 次のサンプルをご覧ください: <ph type="x-smartling-placeholder"></ph> Leanback ショーケース アプリ をタップします。