Thư viện Android Leanback có các bộ điều khiển chế độ phát mới giúp cải thiện trải nghiệm người dùng. Đối với các ứng dụng video, các chế độ điều khiển truyền tải hỗ trợ tua video bằng các chế độ điều khiển tiến/lùi. Trong khi tua qua màn hình, hình thu nhỏ sẽ hiển thị để giúp bạn di chuyển trong video.
Thư viện này bao gồm các lớp trừu tượng cũng như phương pháp triển khai có sẵn giúp cung cấp quyền kiểm soát chi tiết hơn cho nhà phát triển. Bằng cách sử dụng các phương thức triển khai tích hợp sẵn, bạn có thể nhanh chóng xây dựng một ứng dụng nhiều tính năng mà không cần lập trình nhiều. Nếu cần tuỳ chỉnh thêm, bạn có thể mở rộng bất kỳ thành phần nào được tạo sẵn trong thư viện.
Các nút điều khiển và trình phát
Thư viện leanback tách riêng giao diện người dùng bằng các nút điều khiển truyền tải khỏi trình phát phát lại video. Việc này được thực hiện với 2 thành phần: mảnh hỗ trợ phát để hiển thị các nút điều khiển truyền tải (và video (không bắt buộc)) và bộ chuyển đổi trình phát để đóng gói trình phát nội dung đa phương tiện.
Mảnh phát
Hoạt động trên giao diện người dùng của ứng dụng phải sử dụng PlaybackSupportFragment
hoặc VideoSupportFragment
.
Cả hai đều có các nút điều khiển truyền tải leanback:
PlaybackSupportFragment
tạo ảnh động cho các nút điều khiển truyền tải để ẩn/hiển thị các nút điều khiển đó khi cần.VideoSupportFragment
mở rộngPlaybackSupportFragment
và cóSurfaceView
để kết xuất video.
Bạn có thể tuỳ chỉnh ObjectAdapter
của mảnh để cải thiện giao diện người dùng. Ví dụ: sử dụng setAdapter()
để thêm hàng "video có liên quan".
Bộ chuyển đổi trình phát
PlayerAdapter
là một lớp trừu tượng kiểm soát trình phát nội dung đa phương tiện cơ bản. Nhà phát triển có thể chọn phương thức triển khai MediaPlayerAdapter
được tạo sẵn hoặc tự viết phương thức triển khai lớp này.
Dán các mảnh lại với nhau
Bạn phải sử dụng một số "keo kiểm soát" để kết nối mảnh phát lại với trình phát. Thư viện leanback cung cấp 2 loại keo:
PlaybackBannerControlGlue
vẽ các nút điều khiển truyền tải trong mảnh phát lại theo "kiểu cũ", đặt các nút điều khiển đó bên trong một nền mờ. (PlaybackBannerControlGlue
thay thếPlaybackControlGlue
, phiên bản đã ngừng hoạt động.)PlaybackTransportControlGlue
sử dụng các chế độ điều khiển "kiểu mới" có nền trong suốt.
Nếu muốn ứng dụng của mình hỗ trợ tính năng tua video, bạn phải dùng PlaybackTransportControlGlue
.
Bạn cũng cần chỉ định một "máy chủ lưu trữ keo" để liên kết kết nối với mảnh phát, vẽ các nút điều khiển truyền tải trong giao diện người dùng và duy trì trạng thái, đồng thời truyền các sự kiện điều khiển truyền tải trở lại kết nối. Máy chủ lưu trữ phải khớp với loại mảnh phát. Sử dụng PlaybackSupportFragmentGlueHost
với PlaybackFragment
và VideoSupportFragmentGlueHost
với VideoFragment
.
Dưới đây là hình minh hoạ cách các thành phần của điều khiển phương tiện di chuyển leanback kết hợp với nhau:
Mã gắn ứng dụng của bạn lại với nhau phải nằm trong PlaybackSupportFragment
hoặc VideoSupportFragment
xác định giao diện người dùng.
Trong ví dụ sau, ứng dụng tạo một thực thể của PlaybackTransportControlGlue
, đặt tên cho thực thể đó là playerGlue
và kết nối VideoSupportFragment
của ứng dụng đó với một MediaPlayerAdapter
mới tạo. Vì đây là VideoSupportFragment
, nên mã thiết lập sẽ gọi setHost()
để đính kèm VideoSupportFragmentGlueHost
vào playerGlue
. Mã này được đưa vào lớp
mở rộng 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)); } }
Xin lưu ý rằng mã thiết lập cũng xác định PlayerAdapter.Callback
để xử lý các sự kiện từ trình phát nội dung đa phương tiện.
Tuỳ chỉnh keo giao diện người dùng
Bạn có thể tuỳ chỉnh PlaybackBannerControlGlue
và PlaybackTransportControlGlue
để thay đổi PlaybackControlsRow
.
Tuỳ chỉnh tiêu đề và nội dung mô tả
Để tuỳ chỉnh tiêu đề và nội dung mô tả ở đầu các nút điều khiển chế độ phát, hãy ghi đè 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; }
Đang thêm chế độ điều khiển
Keo điều khiển hiển thị các nút điều khiển cho các hành động trong PlaybackControlsRow
.
Các thao tác trong PlaybackControlsRow
được gán thành 2 nhóm: hành động chính và hành động phụ. Các nút điều khiển cho nhóm chính xuất hiện phía trên thanh tìm kiếm và các nút điều khiển cho nhóm phụ xuất hiện bên dưới thanh tìm kiếm. Ban đầu, chỉ có một hành động chính duy nhất cho nút phát/tạm dừng và không có hành động phụ nào.
Bạn có thể thêm hành động vào nhóm chính và phụ bằng cách ghi đè onCreatePrimaryActions()
và 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); }
Bạn phải ghi đè onActionClicked()
để xử lý các thao tác mới.
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. }
Trong các trường hợp đặc biệt, bạn nên triển khai PlaybackTransportRowPresenter
của riêng mình để hiển thị các chế độ điều khiển tuỳ chỉnh và phản hồi các thao tác tìm kiếm bằng PlaybackSeekUi
.
Tua video
Nếu ứng dụng của bạn dùng VideoSupportFragment
và bạn muốn hỗ trợ tua video.
Bạn cần cung cấp phương thức triển khai PlaybackSeekDataProvider
.
Thành phần này cung cấp hình thu nhỏ video được dùng khi cuộn.
Bạn phải triển khai trình cung cấp của riêng mình bằng cách mở rộng PlaybackSeekDataProvider
.
Hãy xem ví dụ trong
ứng dụng Leanback Showcase.
.