Das Leanback UI-Toolkit enthält Wiedergabesteuerelemente, die die Nutzerfreundlichkeit verbessern. Bei Video-Apps unterstützen die Transportsteuerelemente das Scrubbing von Videos mit den Steuerelementen für Vorwärts- und Rückwärtsspulen. Während des Scrubbings werden Thumbnails angezeigt, die die Navigation durch das Video erleichtern.
Die Bibliothek enthält abstrakte Klassen sowie vorgefertigte Implementierungen, die Entwicklern eine detailliertere Steuerung ermöglichen. Mit den vorgefertigten Implementierungen können Sie schnell eine funktionsreiche App ohne viel Code erstellen. Wenn Sie weitere Anpassungen benötigen, können Sie jede der vorgefertigten Komponenten der Bibliothek erweitern.
Steuerelemente und Player
Das Leanback UI-Toolkit trennt die Benutzeroberfläche der Transportsteuerelemente vom Player, der das Video wiedergibt. Dies wird mit zwei Komponenten erreicht: einem Wiedergabe-Support-Fragment zum Anzeigen der Transportsteuerelemente (und optional des Videos) und einem Player-Adapter zum Kapseln eines Media-Players.
Wiedergabe-Fragment
Die UI-Aktivität Ihrer App sollte ein PlaybackSupportFragment oder ein VideoSupportFragment verwenden.
Beide enthalten die Leanback-Transportsteuerelemente:
- Ein
PlaybackSupportFragmentanimiert seine Transportsteuerelemente, um sie nach Bedarf ein- oder auszublenden. - Ein
VideoSupportFragmenterweitertPlaybackSupportFragmentund hat einSurfaceViewzum Rendern von Videos.
Sie können den ObjectAdapter eines Fragments anpassen, um die Benutzeroberfläche zu verbessern. Verwenden Sie beispielsweise setAdapter(), um eine Zeile mit ähnlichen Videos hinzuzufügen.
PlayerAdapter
PlayerAdapter ist eine abstrakte Klasse, die den zugrunde liegenden Media-Player steuert. Entwickler können die vorgefertigte MediaPlayerAdapter-Implementierung auswählen oder eine eigene Implementierung dieser Klasse schreiben.
Teile zusammenfügen
Sie müssen einen „Steuerkleber“ verwenden, um das Wiedergabe-Fragment mit dem Player zu verbinden. Die Leanback-Bibliothek bietet zwei Arten von Klebern:
PlaybackBannerControlGluezeichnet die Transportsteuerelemente im Wiedergabe-Fragment im „alten Stil“ und platziert sie in einem undurchsichtigen Hintergrund.PlaybackBannerControlGlueersetztPlaybackControlGlue, das eingestellt wurde.PlaybackTransportControlGlueverwendet Steuerelemente im „neuen Stil“ mit einem transparenten Hintergrund.

Wenn Ihre App das Scrubbing von Videos unterstützen soll, müssen Sie PlaybackTransportControlGlue verwenden.
Sie müssen auch einen „Kleber-Host“ angeben, der den Kleber an das Wiedergabe-Fragment bindet, die Transportsteuerelemente in der Benutzeroberfläche zeichnet und ihren Status beibehält und Ereignisse der Transportsteuerelemente an den Kleber zurückgibt. Der Host muss dem Typ des Wiedergabe-Fragments entsprechen. Verwenden Sie PlaybackSupportFragmentGlueHost mit einem PlaybackFragment und VideoSupportFragmentGlueHost mit einem VideoFragment.
Hier sehen Sie eine Abbildung, wie die Teile eines Leanback-Transportsteuerelements zusammenpassen:

Der Code, der Ihre App zusammenfügt, sollte sich im PlaybackSupportFragment oder VideoSupportFragment befinden, das die Benutzeroberfläche definiert.
Im folgenden
Beispiel erstellt die App eine Instanz vonPlaybackTransportControlGlue,
benennt sie playerGlue,
und verbindet ihr VideoSupportFragment mit einem neu erstellten MediaPlayerAdapter. Da es sich um ein VideoSupportFragment handelt, ruft der Einrichtungscode setHost() auf, um ein
VideoSupportFragmentGlueHost an playerGlue anzuhängen. Der Code ist in der Klasse enthalten, die das VideoSupportFragment erweitert.
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)); } }
Der Einrichtungscode definiert auch einen PlayerAdapter.Callback, um Ereignisse vom Media-Player zu verarbeiten.
UI-Kleber anpassen
Sie können PlaybackBannerControlGlue und PlaybackTransportControlGlue anpassen, um die PlaybackControlsRow zu ändern.
Titel und Beschreibung anpassen
Wenn Sie den Titel und die Beschreibung oben in den Wiedergabesteuerelementen anpassen möchten, überschreiben Sie 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; }
Steuerelemente hinzufügen
Der Steuerkleber zeigt Steuerelemente für Aktionen in einer PlaybackControlsRow an.
Die Aktionen in der PlaybackControlsRow sind zwei Gruppen zugewiesen: primäre Aktionen und sekundäre Aktionen. Steuerelemente für die primäre Gruppe werden über der Suchleiste und Steuerelemente für die sekundäre Gruppe unter der Suchleiste angezeigt. Anfangs gibt es nur eine primäre Aktion für die Schaltfläche „Wiedergabe/Pause“ und keine sekundären Aktionen.
Sie können Aktionen zu den primären und sekundären Gruppen hinzufügen, indem Sie onCreatePrimaryActions() und onCreateSecondaryActions() überschreiben.
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); }
Sie müssen onActionClicked() überschreiben, um die neuen Aktionen zu verarbeiten.
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 besonderen Fällen möchten Sie möglicherweise einen eigenen PlaybackTransportRowPresenter implementieren, um benutzerdefinierte Steuerelemente zu rendern und mit PlaybackSeekUi auf Suchaktionen zu reagieren.
Video-Scrubbing
Wenn Ihre App ein VideoSupportFragment verwendet und Sie das Scrubbing von Videos unterstützen möchten.

Sie müssen eine Implementierung von PlaybackSeekDataProvider bereitstellen.
Diese Komponente stellt die Video-Thumbnails bereit, die beim Scrollen verwendet werden.
Sie müssen einen eigenen Anbieter implementieren, indem Sie PlaybackSeekDataProvider erweitern.
Ein Beispiel finden Sie in der
Leanback Showcase-App.
.