您可以自訂投放小工具,方法是設定顏色、設定按鈕、文字和縮圖的外觀樣式,以及選擇要顯示的按鈕類型。
自訂應用程式主題
這個範例會建立自訂主題樣式 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>
上述最後三行可讓您定義此主題中引言疊加層、迷你控制器和展開控制器的特定樣式。後續章節會提供相關範例。
自訂投放按鈕
如要在應用程式主題中新增自訂 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>
如果支援資料庫版本較 26.0.0 新,則應使用 setTint
。如果是舊版支援資料庫,請改用 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
有三個可顯示專輯封面和兩個按鈕的版位,如果沒有填入專輯封面,則會顯示三個控制按鈕。
SLOT SLOT SLOT
1 2 3
根據預設,片段會顯示播放/暫停切換按鈕。開發人員可以使用 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">
警告:這個陣列必須包含三個項目,否則會擲回執行階段例外狀況。如果不想在版位中顯示按鈕,請使用 @id/cast_button_type_empty
。
新增自訂按鈕
MiniControllerFragment
支援新增 SDK 未提供的自訂控制按鈕,例如「喜歡」按鈕。步驟如下:
在
MiniControllerFragment
的castControlButtons
屬性中使用@id/cast_button_type_custom
,指定要用來容納自訂按鈕的空格。實作
UIController
的子類別。UIController
包含 SDK 在投放工作階段或媒體工作階段狀態變更時呼叫的方法。UIController
的子類別應將ImageView
做為其中一個參數,並視需要更新其狀態。建立
MiniControllerFragment
子類別,然後覆寫onCreateView
並呼叫getButtonImageViewAt(int)
,以便取得該自訂按鈕的ImageView
。接著呼叫bindViewToUIController(View, UIController)
,將檢視區塊與自訂UIController
建立關聯。如要瞭解如何處理自訂按鈕的動作,請參閱「新增自訂動作」一節中的
MediaIntentReceiver
。以下範例說明如何將第 2 個插槽的按鈕與名為
MyCustomUIController
的UIController
建立關聯:
// 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>
// 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) ... } }
// 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>
選擇按鈕
展開的控制器活動有五個顯示控制按鈕的槽。中間的空格一律會顯示播放/暫停切換按鈕,且無法設定。其他四個位置則可由傳送端應用程式設定 (從左到右)。
SLOT SLOT PLAY/PAUSE SLOT SLOT
1 2 BUTTON 3 4
根據預設,活動會在這些四個位置顯示隱藏式字幕按鈕、跳到上一個項目按鈕、跳到下一個項目按鈕和靜音切換按鈕,從左到右排列。開發人員可以使用屬性 castControlButtons
覆寫要在哪個版位顯示哪些按鈕。支援的控制按鈕清單會定義為 ID 資源,與迷你控制器按鈕的按鈕類型相同。
以下範例會在第二個位置放置快轉按鈕,在第三個位置放置快轉按鈕,並將第一和最後一個位置留空:
// 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>
陣列必須包含四個項目,否則會擲回執行階段例外狀況。如果不想在版位中顯示按鈕,請使用 @id/cast_button_type_empty
。CastContext
可管理此活動的生命週期和呈現方式。
新增自訂按鈕
ExpandedControllerActivity
支援新增 SDK 未提供的自訂控制按鈕,例如「喜歡」按鈕。步驟如下:
在
ExpandedControllerActivity
的castControlButtons
屬性中使用@id/cast_button_type_custom
,指定要用來容納自訂按鈕的空格。接著,您可以使用getButtonImageViewAt(int)
取得該自訂按鈕的ImageView
。實作
UIController
的子類別。UIController
包含 SDK 在投放工作階段或媒體工作階段狀態變更時呼叫的方法。UIController
的子類別應將ImageView
做為其中一個參數,並視需要更新其狀態。建立 ExpandedControllerActivity 子類別,然後覆寫
onCreate
並呼叫getButtonImageViewAt(int)
,以取得按鈕的 View 物件。接著呼叫bindViewToUIController(View, UIController)
,將檢視區塊與自訂UIController
建立關聯。如要瞭解如何處理自訂按鈕的動作,請參閱「新增自訂動作」一文中的
MediaIntentReceiver
。
以下範例說明如何將第 2 個插槽的按鈕與名為 MyCustomUIController
的 UIController
建立關聯:
// 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>
// 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) ... } }
// 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); ... } }