ปรับแต่ง 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

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

ประเภทปุ่ม คำอธิบาย
@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 เพื่อลบล้างปุ่มที่จะแสดงในช่องต่างๆ ได้ รายการปุ่มควบคุมที่รองรับจะกำหนดเป็นทรัพยากรรหัสที่เหมือนกับประเภทปุ่มสำหรับปุ่มตัวควบคุมขนาดเล็ก

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