Utilizzare i controlli per il trasporto

Migliora la creazione con Compose
Crea splendide UI con un minimo codice utilizzando Jetpack Compose per il sistema operativo Android TV.

Il toolkit Leanback UI dispone di controlli di riproduzione che forniscono un un'esperienza utente positiva. Per le app video, i controlli di trasporto supportano lo scrubbing video. con i controlli avanti e indietro. Mentre scorri il display, miniature per facilitare la navigazione all'interno del video.

La libreria include classi astratte e implementazioni predefinite e pronte all'uso che offrono agli sviluppatori un controllo più granulare. Utilizzando i modelli puoi creare rapidamente un'app ricca di funzionalità senza scrivere molto codice. Se hai bisogno di una maggiore personalizzazione, puoi estendere qualsiasi modello predefinito componenti.

Controlli e player

Il toolkit Leanback UI separa l'interfaccia utente dei controlli di trasporto il player che riproduce il video. Questo risultato si ottiene con due componenti: un frammento di supporto della riproduzione per la visualizzazione dei controlli di trasporto (e facoltativamente il video) e un adattatore per il player per incorporare un media player.

Frammento di riproduzione

L'attività UI della tua app deve utilizzare un PlaybackSupportFragment o un VideoSupportFragment. Entrambi contengono i controlli di trasporto leanback:

Puoi personalizzare il valore ObjectAdapter per migliorare l'UI. Ad esempio, utilizza setAdapter() aggiungere un "video correlati" riga di comando.

Adattatore player

PlayerAdapter è una classe astratta controlla il media player sottostante. Gli sviluppatori possono scegliere l'implementazione predefinita di MediaPlayerAdapter, oppure la propria implementazione di questa classe.

Incollamento dei pezzi

Devi usare una "colla di controllo" per collegare il frammento di riproduzione al player. Leanback libreria fornisce due tipi di colla:

colla per controllo trasporto leanback

Se vuoi che la tua app supporti lo scrubbing video, devi usare PlaybackTransportControlGlue.

Devi specificare anche un "glue host" che consente di associare il collante alla riproduzione , disegna i controlli di trasporto nell'interfaccia utente e mantiene il loro stato e e trasmette gli eventi di controllo del trasporto al collante. L'host deve corrispondere al tipo di frammento di riproduzione. Utilizza le funzionalità di PlaybackSupportFragmentGlueHost con un PlaybackFragment e VideoSupportFragmentGlueHost con un VideoFragment.

Ecco un'illustrazione che mostra come gli elementi di un controllo di trasporto si abbinano:

colla per controllo trasporto leanback

Il codice che consente di incollare la tua app deve essere all'interno della sezione PlaybackSupportFragment o VideoSupportFragment che definisce l'UI.

Nel seguente Ad esempio, l'app crea un'istanza di PlaybackTransportControlGlue, denominato playerGlue, e connette il suo VideoSupportFragment a un MediaPlayerAdapter appena creato. Dal giorno questo è un VideoSupportFragment il codice di configurazione chiama setHost() per collegare un VideoSupportFragmentGlueHost a playerGlue. Il codice è incluso all'interno del corso che estende l'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));
  }
}

Tieni presente che il codice di configurazione definisce anche un PlayerAdapter.Callback per la gestione degli eventi da il media player.

Personalizzazione della colla UI

Puoi personalizzare PlaybackBannerControlGlue e PlaybackTransportControlGlue per modificare PlaybackControlsRow.

Personalizzazione del titolo e della descrizione

Per personalizzare il titolo e la descrizione nella parte superiore della controlli di riproduzione, override 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;
}

Aggiunta dei controlli

Il collante di controllo mostra i controlli per le azioni in un PlaybackControlsRow.

Le azioni in PlaybackControlsRow Sono assegnati a due gruppi: azioni principali e secondarie azioni. I controlli per il gruppo principale vengono visualizzati sopra la barra di scorrimento e i controlli per il gruppo gruppo secondario viene visualizzato sotto la barra di scorrimento. Inizialmente è presente una sola azione principale per il pulsante di riproduzione/pausa e nessuna azione secondaria.

Puoi aggiungere azioni ai gruppi principale e secondario eseguendo l'override onCreatePrimaryActions() e 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);
}

Devi eseguire l'override onActionClicked() per gestire le nuove azioni.

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.
}

In casi speciali, ti consigliamo di implementare PlaybackTransportRowPresenter per eseguire il rendering di controlli personalizzati e rispondere alle azioni di ricerca utilizzando PlaybackSeekUi.

Scrubing del video

Se la tua app utilizza un VideoSupportFragment e vuoi supportare lo scrubbing dei video.

strusciarsi

Tu devono fornire un'implementazione di PlaybackSeekDataProvider. Questo componente fornisce le miniature dei video utilizzate durante lo scorrimento. Devi implementare il tuo provider estendendo PlaybackSeekDataProvider. Vedi l'esempio nella App Leanback Showcase. di Google.