Leanback androidx庫中具有新的播放控件,可改善用戶體驗。對于視頻應(yīng)用,傳輸控件transport controls支持使用前進/后退控件進行視頻拖動。拖動時,屏幕上會顯示縮略圖來幫助瀏覽視頻。
該庫中包含抽象類和開箱即用的實現(xiàn),可為開發(fā)者提供更精細的控制。使用預(yù)構(gòu)建實現(xiàn)時,您無需編寫大量代碼即可快速構(gòu)建功能豐富的應(yīng)用。如果需要進行更多自定義設(shè)置,您可以擴展該庫的任何預(yù)構(gòu)建組件。
控件和播放器
Leanback 庫將帶有傳輸控件的界面與播放視頻的播放器分開。這是通過兩個組件實現(xiàn)的:用于顯示傳輸控件(或者視頻)的播放支持 playback support Fragment 和用于封裝媒體播放器的播放器適配器player adapter。
Playback fragment
應(yīng)用的界面 Activity 應(yīng)使用 PlaybackSupportFragment 或 VideoSupportFragment。兩者都包含 Leanback 傳輸控件:
-
PlaybackSupportFragment將其傳輸控件制作成動畫,以根據(jù)需要隱藏/顯示這些控件。 -
VideoSupportFragment擴展了PlaybackSupportFragment并具有用于渲染視頻的SurfaceView。
您可以自定義 Fragment 的ObjectAdapter,以改進界面。例如,使用setAdapter()添加“相關(guān)視頻”行。
PlayerAdapter
PlayerAdapter 是一個用于控制底層媒體播放器的抽象類。開發(fā)者可以選擇預(yù)構(gòu)建的 MediaPlayerAdapter 實現(xiàn),也可以自己編寫該類的實現(xiàn)。
將片段粘合在一起(Glueing the pieces together)
您必須使用某種“控件粘合劑”將播放 Fragment 連接到播放器。Leanback 庫提供兩種粘合劑:
-
PlaybackBannerControlGlue使用“舊樣式”在播放 Fragment 中繪制傳輸控件,并將控件放置在不透明背景中。(PlaybackBannerControlGlue取代了已被棄用的PlaybackControlGlue。) -
PlaybackTransportControlGlue使用具有透明背景的“新樣式”控件。
glue_side_by_side.png
如果您希望應(yīng)用支持視頻拖動,必須使用PlaybackTransportControlGlue。
您還需要指定一個“粘合主機glue host”,將粘合劑綁定到播放 Fragment,在界面中繪制傳輸控件并保持其狀態(tài),然后將傳輸控制事件傳回粘合劑。該主機必須與播放 Fragment 類型匹配。將PlaybackSupportFragmentGlueHost與PlaybackFragment結(jié)合使用,將VideoSupportFragmentGlueHost與VideoFragment結(jié)合使用。
下圖顯示了 Leanback 傳輸控件的各個片段如何粘合在一起:
leanback-control-glue.png
將應(yīng)用粘合在一起的代碼應(yīng)該位于定義界面的 PlaybackSupportFragment 或 VideoSupportFragment 內(nèi)。
在以下示例中,應(yīng)用構(gòu)建了一個名為 playerGlue 的 PlaybackTransportControlGlue 實例,并將其 VideoSupportFragment 連接到新創(chuàng)建的 MediaPlayerAdapter。由于這是一個 VideoSupportFragment,設(shè)置代碼會調(diào)用 setHost() 以將 VideoSupportFragmentGlueHost 附加到 playerGlue。該代碼包含在擴展 VideoSupportFragment 的類中。
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));
}
}
請注意,設(shè)置代碼還定義了 PlayerAdapter.Callback,用于處理來自媒體播放器的事件。
自定義界面粘合劑
您可以自定義 PlaybackBannerControlGlue 和 PlaybackTransportControlGlue,用于更改 PlaybackControlsRow。
自定義標題和描述
如需自定義播放控件頂部的標題和描述,請?zhí)鎿Q onCreateRowPresenter():
@Override
protected PlaybackRowPresenter onCreateRowPresenter() {
PlaybackTransportRowPresenter presenter = (PlaybackTransportRowPresenter) super.onCreateRowPresenter();
presenter.setDescriptionPresenter(new MyCustomDescriptionPresenter());
return presenter;
}
添加控件
控件粘合劑顯示 PlaybackControlsRow 中的操作控件。
PlaybackControlsRow 中的操作分為兩組:主要操作和次要操作。主要操作組的控件顯示在搜索欄上方,次要操作組的控件顯示在搜索欄下方。最初,播放/暫停按鈕只有一個主要操作,沒有次要操作。
您可以通過替換 onCreatePrimaryActions() 和 onCreateSecondaryActions(),向主要操作和次要操作添加操作。
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() 才能處理新操作。
@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.
}
在特殊情況下,您可能想要實現(xiàn)自己的 PlaybackTransportRowPresenter 以渲染自定義控件,并使用 PlaybackSeekUi 以響應(yīng)搜索操作。
視頻拖動
如果應(yīng)用使用 VideoSupportFragment,并且您希望支持視頻拖動。

您需要提供 PlaybackSeekDataProvider 的實現(xiàn)。該組件提供滾動時使用的視頻縮略圖。您必須通過擴展 PlaybackSeekDataProvider 實現(xiàn)自己的提供程序。請參閱 Android TV GitHub 代碼庫中的 Android Leanback Showcase 示例應(yīng)用中的示例。

