Tuỳ chỉnh giao diện người dùng của Android Sender

Bạn có thể tuỳ chỉnh Tiện ích Truyền bằng cách đặt màu, tạo kiểu cho nút, văn bản và hình thu nhỏ cũng như chọn loại nút cần hiển thị.

Tuỳ chỉnh giao diện của ứng dụng

Ví dụ này sẽ tạo một kiểu giao diện tuỳ chỉnh Theme.CastVideosTheme có thể xác định màu tuỳ chỉnh, kiểu lớp phủ giới thiệu, kiểu tay điều khiển thu nhỏ và kiểu tay điều khiển mở rộng.

<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Set AppCompat's color theming attrs -->
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primary_dark</item>
    <item name="colorAccent">@color/accent</item>
    <item name="android:textColorPrimary">@color/primary_text</item>
    <item name="android:textColorSecondary">@color/secondary_text</item>
    <item name="castIntroOverlayStyle">@style/CustomCastIntroOverlay</item>
    <item name="castMiniControllerStyle">@style/CustomCastMiniController</item>
    <item name="castExpandedControllerStyle">@style/CustomCastExpandedController</item>
</style>

Ba dòng cuối cùng ở trên cho phép bạn xác định kiểu dành riêng cho lớp phủ giới thiệu, tay điều khiển thu nhỏ và tay điều khiển mở rộng trong giao diện này. Ví dụ được bao gồm trong các phần tiếp theo.

Tuỳ chỉnh nút Truyền

Cách thêm một mediaRouteTheme tuỳ chỉnh vào Giao diện của ứng dụng:

<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
  <!-- ... -->
  <item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
</style>

Khai báo giao diện tuỳ chỉnh của Bộ định tuyến nội dung đa phương tiện và khai báo một mediaRouteButtonStyle tuỳ chỉnh:

<style name="CustomMediaRouterTheme" parent="Theme.MediaRouter">
  <item name="mediaRouteButtonStyle">@style/CustomMediaRouteButtonStyle</item>
</style>

<style name="CustomMediaRouteButtonStyle" parent="Widget.MediaRouter.Light.MediaRouteButton">
  <item name="mediaRouteButtonTint">#EEFF41</item>
</style>

Bạn nên sử dụng setTint nếu phiên bản thư viện hỗ trợ mới hơn 26.0.0. Đối với các phiên bản thư viện hỗ trợ cũ hơn, vui lòng sử dụng buttonTint.

Tuỳ chỉnh giao diện lớp phủ giới thiệu

Lớp IntroductoryOverlay hỗ trợ nhiều thuộc tính kiểu mà ứng dụng của bạn có thể ghi đè trong một giao diện tuỳ chỉnh. Ví dụ này cho thấy cách ghi đè hình thức văn bản của cả nút và tiêu đề trên tiện ích lớp phủ:

<style name="CustomCastIntroOverlay" parent="CastIntroOverlay">
    <item name="castButtonTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Button</item>
    <item name="castTitleTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Title</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Button" parent="android:style/TextAppearance">
    <item name="android:textColor">#FFFFFF</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Title"parent="android:style/TextAppearance.Large">
    <item name="android:textColor">#FFFFFF</item>
</style>

Tuỳ chỉnh tay điều khiển thu nhỏ

Tùy chỉnh chủ đề

Lớp MiniControllerFragment hỗ trợ nhiều thuộc tính kiểu mà ứng dụng của bạn có thể ghi đè trong một giao diện tuỳ chỉnh. Ví dụ này cho biết cách bật chế độ hiển thị hình thu nhỏ, ghi đè hình thức văn bản của cả tiêu đề phụ và phụ đề chi tiết, đặt màu sắc và tuỳ chỉnh các nút:

<style name="CustomCastMiniController" parent="CastMiniController">
    <item name="castShowImageThumbnail">true</item>
    <item name="castTitleTextAppearance">@style/TextAppearance.AppCompat.Subhead</item>
    <item name="castSubtitleTextAppearance">@style/TextAppearance.AppCompat.Caption</item>
    <item name="castBackground">#FFFFFF</item>
    <item name="castProgressBarColor">#FFFFFF</item>
    <item name="castPlayButtonDrawable">@drawable/cast_ic_mini_controller_play</item>
    <item name="castPauseButtonDrawable">@drawable/cast_ic_mini_controller_pause</item>
    <item name="castStopButtonDrawable">@drawable/cast_ic_mini_controller_stop</item>
    <item name="castLargePlayButtonDrawable">@drawable/cast_ic_mini_controller_play_large</item>
    <item name="castLargePauseButtonDrawable">@drawable/cast_ic_mini_controller_pause_large</item>
    <item name="castLargeStopButtonDrawable">@drawable/cast_ic_mini_controller_stop_large</item>
    <item name="castSkipPreviousButtonDrawable">@drawable/cast_ic_mini_controller_skip_prev</item>
    <item name="castSkipNextButtonDrawable">@drawable/cast_ic_mini_controller_skip_next</item>
    <item name="castRewind30ButtonDrawable">@drawable/cast_ic_mini_controller_rewind30</item>
    <item name="castForward30ButtonDrawable">@drawable/cast_ic_mini_controller_forward30</item>
    <item name="castMuteToggleButtonDrawable">@drawable/cast_ic_mini_controller_mute</item>
    <item name="castClosedCaptionsButtonDrawable">@drawable/cast_ic_mini_controller_closed_caption</item
</style>

Chọn nút

MiniControllerFragment có 3 ô có thể hiển thị ảnh bìa đĩa nhạc và 2 nút, hoặc 3 nút điều khiển nếu không có ảnh bìa đĩa nhạc.

SLOT  SLOT  SLOT
  1     2     3

Theo mặc định, mảnh này sẽ hiện nút bật/tắt phát/tạm dừng. Nhà phát triển có thể sử dụng thuộc tính castControlButtons để ghi đè nút sẽ hiển thị. Các nút điều khiển được hỗ trợ được định nghĩa là tài nguyên mã nhận dạng:

Loại nút Nội dung mô tả
@id/cast_button_type_empty Đừng đặt nút trong vùng này
@id/cast_button_type_custom Nút tuỳ chỉnh
@id/cast_button_type_play_pause_toggle Chuyển đổi giữa chế độ phát và tạm dừng
@id/cast_button_type_skip_previous Chuyển đến mục trước trong hàng đợi
@id/cast_button_type_skip_next Chuyển đến mục tiếp theo trong hàng đợi
@id/cast_button_type_rewind_30_seconds Tua lại 30 giây so với thời điểm phát
@id/cast_button_type_forward_30_seconds Tua đi 30 giây so với nội dung phát
@id/cast_button_type_mute_toggle Tắt tiếng và bật tiếng bộ thu
@id/cast_button_type_closed_caption Mở hộp thoại để chọn bản âm thanh và văn bản

Dưới đây là ví dụ về cách sử dụng ảnh bìa đĩa nhạc, nút bật/tắt phát/tạm dừng và nút tua đi theo thứ tự từ trái sang phải:

<array name="cast_mini_controller_control_buttons">
    <item>@id/cast_button_type_empty</item>
    <item>@id/cast_button_type_play_pause_toggle</item>
    <item>@id/cast_button_type_forward_30_seconds</item>
</array>
...
<fragment
    android:id="@+id/cast_mini_controller"
    ...
    app:castControlButtons="@array/cast_mini_controller_control_buttons"
    class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment">

Cảnh báo: Mảng này phải chứa chính xác 3 mục, nếu không, một ngoại lệ đối với thời gian chạy sẽ được gửi. Nếu bạn không muốn hiển thị nút trong một ô, hãy sử dụng @id/cast_button_type_empty.

Thêm nút tuỳ chỉnh

MiniControllerFragment hỗ trợ thêm các nút điều khiển tuỳ chỉnh không do SDK cung cấp, chẳng hạn như nút "thumb's up". Các bước thực hiện:

  1. Chỉ định một ô để chứa nút tuỳ chỉnh bằng cách sử dụng @id/cast_button_type_custom trong thuộc tính castControlButtons của MiniControllerFragment.

  2. Triển khai một lớp con của UIController. UIController chứa các phương thức mà SDK gọi khi trạng thái của phiên truyền hoặc phiên phát nội dung đa phương tiện thay đổi. Lớp con của UIController phải lấy ImageView làm một trong các tham số và cập nhật trạng thái của tham số đó nếu cần.

  3. Lớp con MiniControllerFragment, sau đó ghi đè onCreateView và gọi getButtonImageViewAt(int) để nhận ImageView cho nút tuỳ chỉnh đó. Sau đó, gọi bindViewToUIController(View, UIController) để liên kết khung hiển thị đó với UIController tuỳ chỉnh của bạn.

  4. Hãy xem MediaIntentReceiver trong phần Thêm thao tác tuỳ chỉnh để biết cách xử lý thao tác từ nút tuỳ chỉnh của bạn.

    Dưới đây là ví dụ về cách liên kết một nút tại vị trí 2 với UIController có tên là MyCustomUIController:

// arrays.xml
<array name="cast_expanded_controller_control_buttons">
    <item>@id/cast_button_type_empty</item>
    <item>@id/cast_button_type_rewind_30_seconds</item>
    <item>@id/cast_button_type_custom</item>
    <item>@id/cast_button_type_empty</item>
</array>
Kotlin
// MyCustomUIController.kt
class MyCustomUIController(private val mView: View) : UIController() {
    override fun onMediaStatusUpdated() {
        // Update the state of mView based on the latest the media status.
        ...
        mView.visibility = View.INVISIBLE
        ...
    }
}

// MyMiniControllerFragment.kt
class MyMiniControllerFragment : MiniControllerFragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        super.onCreateView(inflater, container, savedInstanceState)
        val customButtonView = getButtonImageViewAt(2)
        val myCustomUiController = MyCustomUIController(customButtonView)
        uiMediaController.bindViewToUIController(customButtonView, myCustomUiController)
        ...
    }
}
Java
// MyCustomUIController.java
class MyCustomUIController extends UIController {
    private final View mView;

    public MyCustomUIController(View view) {
            mView = view;
    }

    @Override
    public onMediaStatusUpdated() {
        // Update the state of mView based on the latest the media status.
        ...
        mView.setVisibility(View.INVISIBLE);
        ...
    }
}

// MyMiniControllerFragment.java
class MyMiniControllerFragment extends MiniControllerFragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        ImageView customButtonView = getButtonImageViewAt(2);
        MyCustomUIController myCustomUiController = new MyCustomUIController(customButtonView);
        getUIMediaController().bindViewToUIController(customButtonView, myCustomUiController);
        ...
    }
}

Tuỳ chỉnh bộ điều khiển mở rộng

Tùy chỉnh chủ đề

Nếu Hoạt động của tay điều khiển mở rộng sử dụng thanh công cụ giao diện tối, thì bạn có thể thiết lập một giao diện trên thanh công cụ để sử dụng văn bản sáng và màu biểu tượng sáng:

<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="castExpandedControllerToolbarStyle">
        @style/ThemeOverlay.AppCompat.Dark.ActionBar
    </item>
</style>

Bạn có thể chỉ định hình ảnh của riêng mình dùng để vẽ các nút trên trình điều khiển mở rộng:

<style name="CustomCastExpandedController" parent="CastExpandedController">
    <item name="castButtonColor">@null</item>
    <item name="castPlayButtonDrawable">@drawable/cast_ic_expanded_controller_play</item>
    <item name="castPauseButtonDrawable">@drawable/cast_ic_expanded_controller_pause</item>
    <item name="castStopButtonDrawable">@drawable/cast_ic_expanded_controller_stop</item>
    <item name="castSkipPreviousButtonDrawable">@drawable/cast_ic_expanded_controller_skip_previous</item>
    <item name="castSkipNextButtonDrawable">@drawable/cast_ic_expanded_controller_skip_next</item>
    <item name="castRewind30ButtonDrawable">@drawable/cast_ic_expanded_controller_rewind30</item>
    <item name="castForward30ButtonDrawable">@drawable/cast_ic_expanded_controller_forward30</item>
</style>

Chọn nút

Phần Hoạt động của trình điều khiển mở rộng có 5 ô để hiển thị các nút điều khiển. Ô ở giữa luôn hiển thị nút bật tắt phát/tạm dừng và không thể định cấu hình. 4 ô còn lại có thể được định cấu hình (từ trái sang phải) theo ứng dụng của người gửi.

SLOT  SLOT  PLAY/PAUSE  SLOT  SLOT
  1     2     BUTTON      3     4

Theo mặc định, Activity (Hoạt động) hiển thị một nút phụ đề chi tiết, một nút chuyển đến nút trước đó, một nút chuyển đến nút tiếp theo và một nút bật/tắt tiếng (tắt tiếng) trong 4 ô này, từ trái sang phải. Nhà phát triển có thể sử dụng thuộc tính castControlButtons để ghi đè nút sẽ hiển thị trong vị trí nào. Danh sách các nút điều khiển được hỗ trợ được định nghĩa là tài nguyên mã nhận dạng giống với loại nút cho các nút trên tay điều khiển thu nhỏ.

Dưới đây là một ví dụ đặt một nút tua lại ở khe thứ hai, nút tua đi ở chỗ thứ ba, đồng thời để trống ô đầu tiên và cuối cùng:

// arrays.xml
<array name="cast_expanded_controller_control_buttons">
    <item>@id/cast_button_type_empty</item>
    <item>@id/cast_button_type_rewind_30_seconds</item>
    <item>@id/cast_button_type_forward_30_seconds</item>
    <item>@id/cast_button_type_empty</item>
</array>
...
// styles.xml
<style name="Theme.MyTheme">
    <item name="castExpandedControllerStyle">
        @style/CustomCastExpandedController
    </item>
</style>
...
<style name="CustomCastExpandedController" parent="CastExpandedController">
    <item name="castControlButtons">
        @array/cast_expanded_controller_control_buttons
    </item>
</style>

Mảng này phải chứa đúng 4 mục, nếu không, một ngoại lệ thời gian chạy sẽ được gửi. Nếu bạn không muốn hiển thị nút trong một ô, hãy sử dụng @id/cast_button_type_empty. CastContext có thể quản lý vòng đời và cách trình bày hoạt động này.

Thêm nút tuỳ chỉnh

ExpandedControllerActivity hỗ trợ việc thêm các nút điều khiển tuỳ chỉnh không phải do SDK cung cấp, chẳng hạn như nút "thumb's up". Các bước thực hiện:

  1. Chỉ định một ô để chứa nút tuỳ chỉnh bằng cách sử dụng @id/cast_button_type_custom trong thuộc tính castControlButtons của ExpandedControllerActivity. Sau đó, bạn có thể sử dụng getButtonImageViewAt(int) để lấy ImageView cho nút tuỳ chỉnh đó.

  2. Triển khai một lớp con của UIController. UIController chứa các phương thức mà SDK gọi khi trạng thái của phiên truyền hoặc phiên phát nội dung đa phương tiện thay đổi. Lớp con của UIController phải lấy ImageView làm một trong các tham số và cập nhật trạng thái của tham số đó nếu cần.

  3. Lớp con OpenControllerActivity, sau đó ghi đè onCreate và gọi getButtonImageViewAt(int) để lấy đối tượng khung hiển thị của nút. Sau đó, gọi bindViewToUIController(View, UIController) để liên kết khung hiển thị đó với UIController tuỳ chỉnh của bạn.

  4. Hãy xem MediaIntentReceiver trong phần Thêm thao tác tuỳ chỉnh để biết cách xử lý thao tác từ nút tuỳ chỉnh của bạn.

Dưới đây là ví dụ về cách liên kết một nút tại vị trí 2 với UIController có tên là MyCustomUIController:

// arrays.xml
<array name="cast_expanded_controller_control_buttons">
    <item>@id/cast_button_type_empty</item>
    <item>@id/cast_button_type_rewind_30_seconds</item>
    <item>@id/cast_button_type_custom</item>
    <item>@id/cast_button_type_empty</item>
</array>
Kotlin
// MyCustomUIController.kt
class MyCustomUIController(private val mView: View) : UIController() {
    override fun onMediaStatusUpdated() {
        // Update the state of mView based on the latest the media status.
        ...
        mView.visibility = View.INVISIBLE
        ...
    }
}

// MyExpandedControllerActivity.kt
internal class MyExpandedControllerActivity : ExpandedControllerActivity() {
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val customButtonView = getButtonImageViewAt(2)
        val myCustomUiController = MyCustomUIController(customButtonView)
        uiMediaController.bindViewToUIController(customButtonView, myCustomUiController)
        ...
    }
}
Java
// MyCustomUIController.java
class MyCustomUIController extends UIController {
    private final View mView;

    public MyCustomUIController(View view) {
        mView = view;
    }

    @Override
    public onMediaStatusUpdated() {
        // Update the state of mView based on the latest the media status.
        ...
        mView.setVisibility(View.INVISIBLE);
        ...
    }
}

// MyExpandedControllerActivity.java
class MyExpandedControllerActivity extends ExpandedControllerActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ImageView customButtonView = getButtonImageViewAt(2);
        MyCustomUIController myCustomUiController = new MyCustomUIController(customButtonView);
        getUIMediaController().bindViewToUIController(customButtonView, myCustomUiController);
        ...
    }
}