Menyesuaikan UI Pengirim Android

Anda dapat menyesuaikan widget Cast dengan menyetel warna, menata gaya tampilan tombol, teks, dan thumbnail, serta dengan memilih jenis tombol yang akan ditampilkan.

Menyesuaikan tema aplikasi

Contoh ini membuat gaya tema kustom Theme.CastVideosTheme yang dapat menentukan warna kustom, gaya overlay pengantar, gaya pengontrol mini, dan gaya pengontrol yang diperluas.

<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>

Tiga baris terakhir di atas memungkinkan Anda menentukan gaya khusus overlay pengantar, pengontrol mini, dan pengontrol yang diperluas sebagai bagian dari tema ini. Contoh disertakan di bagian yang mengikutinya.

Sesuaikan Tombol Cast

Untuk menambahkan mediaRouteTheme kustom ke Tema aplikasi Anda:

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

Deklarasikan tema Router Media kustom Anda dan deklarasikan mediaRouteButtonStyle kustom:

<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>

setTint harus digunakan jika versi support library lebih baru dari 26.0.0. Untuk versi support library yang lebih lama, gunakan buttonTint.

Menyesuaikan Tema Overlay Pengantar

Class IntroductoryOverlay mendukung berbagai atribut gaya yang dapat diganti aplikasi Anda dalam tema kustom. Contoh ini menunjukkan cara mengganti tampilan teks tombol dan judul pada widget overlay:

<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>

Sesuaikan pengontrol mini

Menyesuaikan tema

Class MiniControllerFragment mendukung berbagai atribut gaya yang dapat diganti aplikasi Anda dalam tema kustom. Contoh ini menunjukkan cara mengaktifkan tampilan gambar thumbnail, untuk mengganti tampilan teks subjudul dan teks tertutup, menyetel warna, dan menyesuaikan tombol:

<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>

Pilih tombol

MiniControllerFragment memiliki tiga slot yang dapat menampilkan sampul album dan dua tombol, atau tiga tombol kontrol jika sampul album tidak diisi.

SLOT  SLOT  SLOT
  1     2     3

Secara default, fragmen menampilkan tombol putar/jeda. Developer dapat menggunakan atribut castControlButtons untuk mengganti tombol yang akan ditampilkan. Tombol kontrol yang didukung ditentukan sebagai resource ID:

Jenis Tombol Deskripsi
@id/cast_button_type_empty Jangan tempatkan tombol di slot ini
@id/cast_button_type_custom Tombol khusus
@id/cast_button_type_play_pause_toggle Beralih antara pemutaran dan jeda
@id/cast_button_type_skip_previous Melewati ke item sebelumnya dalam antrean
@id/cast_button_type_skip_next Melewati ke item berikutnya dalam antrean
@id/cast_button_type_rewind_30_seconds Memutar ulang pemutaran 30 detik
@id/cast_button_type_forward_30_seconds Melewati pemutaran video sejauh 30 detik
@id/cast_button_type_mute_toggle Membisukan dan membunyikan penerima
@id/cast_button_type_closed_caption Membuka dialog untuk memilih trek teks dan audio

Berikut adalah contoh yang akan menggunakan sampul album, tombol putar/jeda, dan tombol lewati maju dalam urutan tersebut dari kiri ke kanan:

<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">

Peringatan: Array ini harus berisi tepat tiga item. Jika tidak, pengecualian runtime akan ditampilkan. Jika tidak ingin menampilkan tombol dalam slot, gunakan @id/cast_button_type_empty.

Menambahkan tombol khusus

MiniControllerFragment mendukung penambahan tombol kontrol kustom yang tidak disediakan oleh SDK, seperti tombol "suka". Langkah-langkahnya adalah:

  1. Tentukan slot untuk memuat tombol khusus menggunakan @id/cast_button_type_custom dalam atribut castControlButtons dari MiniControllerFragment.

  2. Implementasikan subclass UIController. UIController berisi metode yang dipanggil oleh SDK saat status sesi transmisi atau sesi media berubah. Subclass UIController harus menggunakan ImageView sebagai salah satu parameter dan memperbarui statusnya sesuai kebutuhan.

  3. Buat subclass MiniControllerFragment, lalu ganti onCreateView dan panggil getButtonImageViewAt(int) untuk mendapatkan ImageView tombol kustom tersebut. Lalu, panggil bindViewToUIController(View, UIController) untuk mengaitkan tampilan dengan UIController kustom.

  4. Lihat MediaIntentReceiver di Menambahkan Tindakan Kustom untuk mengetahui cara menangani tindakan dari tombol kustom Anda.

    Berikut adalah contoh yang mengaitkan tombol di slot 2 ke UIController yang disebut 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);
        ...
    }
}

Menyesuaikan pengontrol yang diperluas

Menyesuaikan tema

Jika Aktivitas pengontrol yang diperluas menggunakan toolbar tema gelap, Anda dapat menetapkan tema pada toolbar untuk menggunakan teks terang dan warna ikon terang:

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

Anda dapat menentukan gambar Anda sendiri yang akan digunakan untuk menggambar tombol pada pengontrol yang diperluas:

<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>

Pilih tombol

Aktivitas pengontrol yang diperluas memiliki lima slot untuk menampilkan tombol kontrol. Slot tengah selalu menampilkan tombol putar/jeda dan tidak dapat dikonfigurasi. Empat slot lainnya dapat dikonfigurasi, dari kiri ke kanan, oleh aplikasi pengirim.

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

Secara default, Aktivitas menampilkan tombol teks tertutup, tombol lewati ke item sebelumnya, tombol lewati ke item berikutnya, dan tombol bisukan di empat slot ini, dari kiri ke kanan. Developer dapat menggunakan atribut castControlButtons untuk mengganti tombol yang akan ditampilkan di slot tertentu. Daftar tombol kontrol yang didukung didefinisikan sebagai resource ID yang identik dengan jenis tombol untuk tombol pengontrol mini.

Berikut adalah contoh yang menempatkan tombol mundur di slot kedua, tombol lewati maju di slot ketiga, serta membiarkan slot pertama dan terakhir kosong:

// 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>

Array harus berisi persis empat item. Jika tidak, pengecualian runtime akan ditampilkan. Jika tidak ingin menampilkan tombol dalam slot, gunakan @id/cast_button_type_empty. CastContext dapat mengelola siklus proses dan presentasi aktivitas ini.

Menambahkan tombol khusus

ExpandedControllerActivity mendukung penambahan tombol kontrol kustom yang tidak disediakan oleh SDK, seperti tombol "jempol ke atas". Langkah-langkahnya adalah:

  1. Tentukan slot untuk memuat tombol khusus menggunakan @id/cast_button_type_custom dalam atribut castControlButtons dari ExpandedControllerActivity. Anda kemudian dapat menggunakan getButtonImageViewAt(int) untuk mendapatkan ImageView untuk tombol khusus tersebut.

  2. Implementasikan subclass UIController. UIController berisi metode yang dipanggil oleh SDK saat status sesi transmisi atau sesi media berubah. Subclass UIController Anda harus menggunakan ImageView sebagai salah satu parameter, dan memperbarui statusnya sesuai kebutuhan.

  3. Buat subclass ExpandedControllerActivity, lalu ganti onCreate dan panggil getButtonImageViewAt(int) untuk mendapatkan objek tampilan tombol. Selanjutnya, panggil bindViewToUIController(View, UIController) untuk mengaitkan tampilan dengan UIController kustom.

  4. Lihat MediaIntentReceiver di Menambahkan Tindakan Kustom untuk mengetahui cara menangani tindakan dari tombol kustom.

Berikut adalah contoh yang mengaitkan tombol di slot 2 ke UIController yang disebut 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);
        ...
    }
}