ปรับแต่ง UI ผู้ส่งของ Android

คุณปรับแต่งวิดเจ็ต Cast ได้โดยการตั้งค่าสี จัดรูปแบบปุ่ม ข้อความ และลักษณะที่ปรากฏของภาพปก รวมถึงเลือกประเภทปุ่มที่จะแสดง

ปรับแต่งธีมแอป

ตัวอย่างนี้สร้างรูปแบบธีมที่กำหนดเอง Theme.CastVideosTheme ซึ่ง กำหนดสีที่กำหนดเอง รูปแบบภาพซ้อนทับเบื้องต้น รูปแบบมินิคอนโทรลเลอร์ และรูปแบบคอนโทรลเลอร์แบบขยายได้

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

3 บรรทัดสุดท้ายด้านบนช่วยให้คุณกำหนดสไตล์เฉพาะสำหรับ การซ้อนทับตอนต้น ตัวควบคุมขนาดเล็ก และตัวควบคุมแบบขยาย ซึ่งเป็นส่วนหนึ่งของธีมนี้ได้ ตัวอย่างจะอยู่ในส่วนที่ตามมา

ปรับแต่งปุ่มแคสต์

วิธีเพิ่ม mediaRouteTheme ที่กำหนดเองลงในธีมของแอป

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

ประกาศธีม Media Router ที่กำหนดเองและประกาศ mediaRouteButtonStyleที่กำหนดเอง

<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 ควรใช้หากไลบรารีการสนับสนุนมีเวอร์ชันใหม่กว่า 26.0.0 สำหรับไลบรารีการสนับสนุนเวอร์ชันเก่า โปรดใช้ buttonTint แทน

ปรับแต่งธีมการซ้อนทับแนะนำ

คลาส IntroductoryOverlay รองรับแอตทริบิวต์สไตล์ต่างๆ ที่แอปของคุณสามารถลบล้างในธีมที่กำหนดเองได้ ตัวอย่างนี้แสดงวิธีลบล้างลักษณะที่ปรากฏของข้อความทั้งปุ่ม และชื่อเหนือวิดเจ็ตซ้อนทับ

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

ปรับแต่งมินิคอนโทรลเลอร์

ปรับแต่งธีม

คลาส MiniControllerFragment รองรับแอตทริบิวต์สไตล์ต่างๆ ที่แอปของคุณสามารถลบล้างในธีมที่กำหนดเองได้ ตัวอย่างนี้แสดงวิธีเปิดใช้การแสดงรูปภาพขนาดย่อ เพื่อ ลบล้างลักษณะข้อความของทั้งส่วนหัวย่อยและคำบรรยายแทนเสียง ตั้งค่า สี และปรับแต่งปุ่ม

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

เลือกปุ่ม

MiniControllerFragment มี 3 ช่องที่แสดงภาพปกอัลบั้ม และปุ่ม 2 ปุ่ม หรือปุ่มควบคุม 3 ปุ่มหากไม่มีภาพปกอัลบั้ม

SLOT  SLOT  SLOT
  1     2     3

โดยค่าเริ่มต้น Fragment จะแสดงปุ่มสลับเล่น/หยุดชั่วคราว นักพัฒนาแอปสามารถใช้แอตทริบิวต์ castControlButtons เพื่อลบล้างปุ่มที่จะแสดง ปุ่มควบคุมที่รองรับมีคำจำกัดความดังนี้ ทรัพยากร ID:

ประเภทปุ่ม คำอธิบาย
@id/cast_button_type_empty อย่าวางปุ่มในช่องนี้
@id/cast_button_type_custom ปุ่มที่กำหนดเอง
@id/cast_button_type_play_pause_toggle สลับระหว่างเล่นและหยุดชั่วคราว
@id/cast_button_type_skip_previous ข้ามไปยังรายการก่อนหน้าในคิว
@id/cast_button_type_skip_next ข้ามไปยังรายการถัดไปในคิว
@id/cast_button_type_rewind_30_seconds กรอกลับการเล่น 30 วินาที
@id/cast_button_type_forward_30_seconds ข้ามไปข้างหน้า 30 วินาที
@id/cast_button_type_mute_toggle ปิดและเปิดเสียงตัวรับ
@id/cast_button_type_closed_caption เปิดกล่องโต้ตอบเพื่อเลือกแทร็กข้อความและเสียง

ตัวอย่างต่อไปนี้จะใช้ภาพปกอัลบั้ม ปุ่มสลับเล่น/หยุดชั่วคราว และปุ่มข้ามไปข้างหน้าตามลำดับจากซ้ายไปขวา

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

คำเตือน: อาร์เรย์นี้ต้องมีรายการ 3 รายการเท่านั้น มิเช่นนั้นระบบจะส่งข้อยกเว้นรันไทม์ หากไม่ต้องการแสดงปุ่มในช่อง ให้ใช้ @id/cast_button_type_empty

เพิ่มปุ่มที่กำหนดเอง

MiniControllerFragment รองรับการเพิ่มปุ่มควบคุมที่กำหนดเองซึ่ง SDK ไม่ได้ให้ไว้ เช่น ปุ่ม "กดถูกใจ" ขั้นตอนมีดังต่อไปนี้

  1. ระบุช่องเพื่อใส่ปุ่มที่กำหนดเองโดยใช้ @id/cast_button_type_custom ในแอตทริบิวต์ castControlButtons ของ MiniControllerFragment

  2. ใช้คลาสย่อยของ UIController UIControllerมีเมธอดที่ SDK เรียกใช้เมื่อสถานะของเซสชันการแคสต์หรือเซสชันสื่อมีการเปลี่ยนแปลง คลาสย่อยของ UIController ควรใช้ ImageView เป็นหนึ่งในพารามิเตอร์และอัปเดตสถานะตามที่จำเป็น

  3. สร้างคลาสย่อย MiniControllerFragment, จากนั้นแทนที่ onCreateView แล้วเรียกใช้ getButtonImageViewAt(int) เพื่อรับ ImageView สำหรับปุ่มที่กำหนดเองนั้น จากนั้นเรียกใช้ bindViewToUIController(View, UIController) เพื่อเชื่อมโยงมุมมองกับUIControllerที่กำหนดเอง

  4. ดูวิธีจัดการการดำเนินการจากปุ่มที่กำหนดเองได้ที่ MediaIntentReceiver เพิ่มการดำเนินการที่กำหนดเอง

    ตัวอย่างการเชื่อมโยงปุ่มในช่องที่ 2 กับ UIController ที่ชื่อ 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);
        ...
    }
}

ปรับแต่งคอนโทรลเลอร์แบบขยาย

ปรับแต่งธีม

หากกิจกรรมของตัวควบคุมแบบขยายใช้แถบเครื่องมือธีมมืด คุณจะตั้งค่าธีมในแถบเครื่องมือให้ใช้ข้อความสีอ่อนและไอคอนสีอ่อนได้โดยทำดังนี้

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

คุณระบุรูปภาพของคุณเองที่จะใช้ในการวาดปุ่มบน ตัวควบคุมแบบขยายได้ดังนี้

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

เลือกปุ่ม

กิจกรรมของตัวควบคุมที่ขยายจะมี 5 ช่องเพื่อแสดงปุ่มควบคุม โดยช่องตรงกลาง จะแสดงปุ่มเปิด/ปิดเล่น/หยุดชั่วคราวเสมอและกำหนดค่าไม่ได้ ส่วนอีก 4 ช่อง ผู้ส่งแอปจะกำหนดค่าได้จากซ้ายไปขวา

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

โดยค่าเริ่มต้น กิจกรรมจะแสดงปุ่มคำบรรยายแทนเสียง ปุ่มข้ามไปยัง รายการก่อนหน้า ปุ่มข้ามไปยังรายการถัดไป และปุ่มสลับปิดเสียง ใน 4 ช่องนี้จากซ้ายไปขวา นักพัฒนาแอปสามารถใช้แอตทริบิวต์ castControlButtons เพื่อลบล้างปุ่มที่จะแสดงใน ช่องใด รายการปุ่มควบคุมที่รองรับจะกำหนดเป็น ทรัพยากร ID ที่เหมือนกับ ประเภทปุ่มสำหรับปุ่มตัวควบคุมขนาดเล็ก

ต่อไปนี้คือตัวอย่างที่วางปุ่มกรอถอยหลังในช่องที่ 2 ปุ่มข้าม ไปข้างหน้าในช่องที่ 3 และปล่อยให้ช่องแรกและช่องสุดท้ายว่างไว้

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

อาร์เรย์ต้องมีรายการ 4 รายการเท่านั้น ไม่เช่นนั้นระบบจะ ยกเว้นรันไทม์ หากไม่ต้องการแสดงปุ่มในช่อง ให้ใช้ @id/cast_button_type_empty CastContext สามารถจัดการวงจรและการนำเสนอกิจกรรมนี้ได้

เพิ่มปุ่มที่กำหนดเอง

ExpandedControllerActivity รองรับการเพิ่มปุ่มควบคุมที่กำหนดเองซึ่ง SDK ไม่ได้ให้ไว้ เช่น ปุ่ม "ชอบ" ขั้นตอนมีดังต่อไปนี้

  1. ระบุช่องเพื่อใส่ปุ่มที่กำหนดเองโดยใช้ @id/cast_button_type_custom ในแอตทริบิวต์ castControlButtons ของ ExpandedControllerActivity จากนั้นคุณจะใช้ getButtonImageViewAt(int) เพื่อรับ ImageView สำหรับปุ่มที่กำหนดเองนั้นได้

  2. ใช้คลาสย่อยของ UIController UIController มีเมธอดที่ SDK เรียกใช้เมื่อสถานะ ของเซสชันการแคสต์หรือเซสชันสื่อมีการเปลี่ยนแปลง คลาสย่อยของ UIController ควรใช้ ImageView เป็นหนึ่งในพารามิเตอร์ และอัปเดตสถานะตามที่จำเป็น

  3. สร้างคลาสย่อย ExpandedControllerActivity จากนั้นแทนที่ onCreate และเรียกใช้ getButtonImageViewAt(int) เพื่อรับออบเจ็กต์มุมมองของปุ่ม จากนั้นเรียกใช้ bindViewToUIController(View, UIController) เพื่อเชื่อมโยงมุมมองกับ UIController ที่กำหนดเอง

  4. ดู MediaIntentReceiver ที่เพิ่มการดำเนินการที่กำหนดเอง เพื่อดูวิธีจัดการการดำเนินการจากปุ่มที่กำหนดเอง

ตัวอย่างการเชื่อมโยงปุ่มในช่องที่ 2 กับ UIController ที่ชื่อ 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);
        ...
    }
}