Toolkit UI Leanback memiliki kontrol pemutaran yang memberikan pengalaman pengguna yang lebih baik. Untuk aplikasi video, kontrol transpor mendukung pemolesan video dengan kontrol maju dan mundur. Saat memoles, layar menampilkan thumbnail untuk membantu menavigasi video.
Library ini mencakup class abstrak serta implementasi siap pakai bawaan yang memberikan kontrol yang lebih terperinci kepada developer. Dengan implementasi bawaan, Anda dapat membuat aplikasi yang kaya fitur dengan cepat, tanpa banyak coding. Jika memerlukan penyesuaian lebih lanjut, Anda dapat memperluas komponen bawaan library.
Kontrol dan pemutar
Toolkit UI Leanback memisahkan UI kontrol transpor dari pemutar yang memutar video. Hal ini dilakukan dengan dua komponen: fragmen dukungan pemutaran untuk menampilkan kontrol transpor (dan ((opsional) video) dan adaptor pemutar untuk mengenkapsulasi pemutar media.
Playback fragment
Aktivitas UI aplikasi Anda harus menggunakan
PlaybackSupportFragment
atau
VideoSupportFragment
.
Keduanya berisi kontrol transport leanback:
PlaybackSupportFragment
menganimasikan kontrol transportnya untuk disembunyikan/ditampilkan sesuai kebutuhan.VideoSupportFragment
memperluasPlaybackSupportFragment
dan memilikiSurfaceView
untuk merender video.
Anda bisa menyesuaikan elemen
ObjectAdapter
untuk meningkatkan UI. Misalnya, gunakan
setAdapter()
untuk menambahkan baris "video terkait".
PlayerAdapter
PlayerAdapter
adalah class abstrak yang
mengontrol pemutar media yang mendasarinya. Developer dapat memilih
implementasi MediaPlayerAdapter
bawaan, atau menulis
implementasi class ini sendiri.
Menyatukan bagian-bagian
Anda harus menggunakan beberapa "perekat kontrol" untuk menghubungkan fragmen pemutaran ke pemutar. Garis miring {i>library<i} menyediakan dua jenis perekat:
PlaybackBannerControlGlue
menarik kontrol transport di fragmen pemutaran dalam "gaya lama", menempatkannya pada latar belakang buram. (PlaybackBannerControlGlue
menggantikanPlaybackControlGlue
, yang sudah tidak digunakan lagi.)PlaybackTransportControlGlue
menggunakan kontrol "gaya baru" dengan latar belakang transparan.
Jika ingin aplikasi Anda mendukung pemolesan video, Anda harus menggunakan
PlaybackTransportControlGlue
.
Anda juga harus menentukan "host perekat" yang
mengikat perekat ke playback
fragment, menggambar kontrol transport di UI dan mempertahankan statusnya, serta
meneruskan peristiwa kontrol transport kembali ke perekat. Host harus cocok dengan jenis playback fragment. Gunakan
PlaybackSupportFragmentGlueHost
dengan
PlaybackFragment
, dan
VideoSupportFragmentGlueHost
dengan
VideoFragment
.
Berikut adalah ilustrasi yang menunjukkan bagaimana bagian kontrol transport Lean saling bekerja sama:
Kode yang merekatkan aplikasi Anda harus berada di dalam
PlaybackSupportFragment
atau VideoSupportFragment
yang menentukan UI.
Dalam
misalnya, aplikasi membuat instance PlaybackTransportControlGlue
,
menamainya playerGlue
,
dan menghubungkan VideoSupportFragment
-nya ke MediaPlayerAdapter
yang baru dibuat. Sejak
ini adalah VideoSupportFragment
yang dipanggil kode penyiapan setHost()
untuk melampirkan
VideoSupportFragmentGlueHost
ke playerGlue
. Kode disertakan di dalam class
yang memperluas 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)); } }
Perhatikan bahwa kode penyiapan juga menentukan PlayerAdapter.Callback
untuk menangani peristiwa dari
pemutar media.
Menyesuaikan perekat UI
Anda dapat menyesuaikan
PlaybackBannerControlGlue
dan PlaybackTransportControlGlue
untuk mengubah
PlaybackControlsRow
.
Menyesuaikan judul dan deskripsi
Untuk menyesuaikan judul dan deskripsi di bagian atas kontrol pemutaran, ganti 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; }
Menambahkan kontrol
Perekat kontrol menampilkan kontrol untuk tindakan dalam PlaybackControlsRow
.
Tindakan dalam PlaybackControlsRow
ditetapkan ke dua grup: tindakan primer dan tindakan
sekunder. Kontrol untuk grup utama muncul di atas kolom pencarian, sedangkan kontrol untuk
grup sekunder muncul di bawah kolom pencarian. Awalnya, hanya ada satu tindakan utama
untuk tombol putar/jeda, dan tidak ada tindakan sekunder.
Anda dapat menambahkan tindakan ke grup utama dan sekunder dengan mengganti
onCreatePrimaryActions()
dan
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); }
Anda harus mengganti
onActionClicked()
untuk menangani tindakan baru.
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. }
Dalam kasus khusus, Anda dapat mengimplementasikan
PlaybackTransportRowPresenter
Anda sendiri untuk merender kontrol kustom dan merespons tindakan pencarian menggunakan
PlaybackSeekUi
.
Memoles video
Jika aplikasi menggunakan VideoSupportFragment
dan Anda ingin mendukung pemolesan video.
Anda
perlu menyediakan implementasi PlaybackSeekDataProvider
.
Komponen ini menyediakan thumbnail video yang digunakan saat melakukan scrolling.
Anda harus mengimplementasikan penyedia Anda sendiri dengan memperluas
PlaybackSeekDataProvider
.
Lihat contohnya di
Aplikasi Leanback Showcase.
kami.