Tuỳ chỉnh giao diện người dùng

Media3 cung cấp một PlayerView mặc định với một số lựa chọn tuỳ chỉnh.

Ghi đè đối tượng có thể vẽ

PlayerView dùng PlayerControlView để hiển thị các chế độ phát và thanh tiến trình. Các đối tượng có thể vẽ mà PlayerControlView sử dụng có thể bị ghi đè bằng các đối tượng có thể vẽ có cùng tên được xác định trong ứng dụng của bạn. Hãy xem tài liệu PlayerControlView để biết danh sách các đối tượng có thể vẽ của thành phần có thể bị ghi đè.

Để tuỳ chỉnh thêm, nhà phát triển ứng dụng phải triển khai các thành phần giao diện người dùng của riêng họ. Tuy nhiên, bạn có thể tham khảo một số phương pháp hay nhất sau đây để bắt đầu.

Các phương pháp hay nhất

Khi triển khai giao diện người dùng nội dung nghe nhìn kết nối với một Player Media3 (ví dụ: ExoPlayer, MediaController hoặc một chế độ triển khai Player tuỳ chỉnh), các ứng dụng nên làm theo những phương pháp hay nhất này để có trải nghiệm giao diện người dùng tốt nhất.

Nút Phát/Tạm dừng

Nút phát và tạm dừng không tương ứng trực tiếp với một trạng thái trình phát duy nhất. Ví dụ: người dùng có thể khởi động lại quá trình phát sau khi quá trình này kết thúc hoặc không thành công, ngay cả khi trình phát không bị tạm dừng.

Để đơn giản hoá việc triển khai, Media3 cung cấp các phương thức tiện ích để quyết định nút nào sẽ hiển thị (Util.shouldShowPlayButton) và để xử lý thao tác nhấn nút (Util.handlePlayPauseButtonAction):

Kotlin

val shouldShowPlayButton: Boolean = Util.shouldShowPlayButton(player)
playPauseButton.setImageDrawable(if (shouldShowPlayButton) playDrawable else pauseDrawable)
playPauseButton.setOnClickListener { Util.handlePlayPauseButtonAction(player) }

Java

boolean shouldShowPlayButton = Util.shouldShowPlayButton(player);
playPauseButton.setImageDrawable(shouldShowPlayButton ? playDrawable : pauseDrawable);
playPauseButton.setOnClickListener(view -> Util.handlePlayPauseButtonAction(player));

Theo dõi thông tin cập nhật về trạng thái

Thành phần giao diện người dùng cần thêm một Player.Listener để được thông báo về các thay đổi trạng thái yêu cầu cập nhật giao diện người dùng tương ứng. Hãy xem bài viết Nghe các sự kiện phát để biết thông tin chi tiết.

Việc làm mới giao diện người dùng có thể tốn kém và nhiều sự kiện của trình phát thường xuất hiện cùng nhau. Để tránh làm mới giao diện người dùng quá thường xuyên trong một khoảng thời gian ngắn, thông thường, bạn chỉ nên theo dõi onEvents và kích hoạt các bản cập nhật giao diện người dùng từ đó:

Kotlin

player.addListener(object : Player.Listener{
  override fun onEvents(player: Player, events: Player.Events){
    if (events.containsAny(
        Player.EVENT_PLAY_WHEN_READY_CHANGED,
        Player.EVENT_PLAYBACK_STATE_CHANGED,
        Player.EVENT_PLAYBACK_SUPPRESSION_REASON_CHANGED)) {
      updatePlayPauseButton()
    }
    if (events.containsAny(Player.EVENT_REPEAT_MODE_CHANGED)) {
      updateRepeatModeButton()
    }
  }
})

Java

player.addListener(new Player.Listener() {
  @Override
  public void onEvents(Player player, Player.Events events) {
    if (events.containsAny(
        Player.EVENT_PLAY_WHEN_READY_CHANGED,
        Player.EVENT_PLAYBACK_STATE_CHANGED,
        Player.EVENT_PLAYBACK_SUPPRESSION_REASON_CHANGED)) {
      updatePlayPauseButton();
    }
    if (events.containsAny(Player.EVENT_REPEAT_MODE_CHANGED)) {
      updateRepeatModeButton();
    }
  }
});

Các lệnh có thể dùng

Một thành phần giao diện người dùng đa năng có thể cần hoạt động với nhiều cách triển khai Player phải kiểm tra các lệnh có sẵn của trình phát để hiện hoặc ẩn các nút và tránh gọi các phương thức không được hỗ trợ:

Kotlin

nextButton.isEnabled = player.isCommandAvailable(Player.COMMAND_SEEK_TO_NEXT)

Java

nextButton.setEnabled(player.isCommandAvailable(Player.COMMAND_SEEK_TO_NEXT));

Màn trập khung hình đầu tiên và màn hình hiển thị hình ảnh

Khi một thành phần giao diện người dùng hiển thị video hoặc hình ảnh, thành phần này thường sử dụng khung hiển thị màn trập giữ chỗ cho đến khi có khung hình hoặc hình ảnh đầu tiên thực sự. Ngoài ra, chế độ phát video và hình ảnh hỗn hợp yêu cầu ẩn và hiện khung hiển thị hình ảnh vào những thời điểm thích hợp.

Một mẫu phổ biến để xử lý những nội dung cập nhật này là lắng nghe Player.Listener.onEvents() để biết mọi thay đổi về các bản nhạc đã chọn (EVENT_TRACKS_CHANGED) và thời điểm khung hình video đầu tiên được kết xuất (EVENT_RENDERED_FIRST_FRAME), cũng như ImageOutput.onImageAvailable() để biết thời điểm có hình ảnh mới:

Kotlin

override fun onEvents(player: Player, events: Player.Events) {
  if (events.contains(Player.EVENT_TRACKS_CHANGED)) {
    // If no video or image track: show shutter, hide image view.
    // Otherwise: do nothing to wait for first frame or image.
  }
  if (events.contains(Player.EVENT_RENDERED_FIRST_FRAME)) {
    // Hide shutter, hide image view.
  }
}

override fun onImageAvailable(presentationTimeUs: Long, bitmap: Bitmap) {
  // Show shutter, set image and show image view.
}

Java

@Override
public void onEvents(Player player, Events events) {
  if (events.contains(Player.EVENT_TRACKS_CHANGED)) {
    // If no video or image track: show shutter, hide image view.
    // Otherwise: do nothing to wait for first frame or image.
  }
  if (events.contains(Player.EVENT_RENDERED_FIRST_FRAME)) {
    // Hide shutter, hide image view.
  }
}

@Override
public void onImageAvailable(long presentationTimeUs, Bitmap bitmap) {
  // Show shutter, set image and show image view.
}