自定义 Android 发送者界面

您可以自定义 Cast widget 通过设置颜色,设置按钮、文本和缩略图的样式, 外观以及选择要显示的按钮类型。

自定义应用主题

此示例创建了一个自定义主题样式 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>

声明自定义媒体路由器主题并声明自定义 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 有三个槽,可以显示专辑封面 和两个按钮或三个控制按钮(如果未填充专辑封面)。

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

警告:此数组必须正好包含三项,否则运行时 但系统会抛出异常如果您不想在槽中显示按钮,请使用 @id/cast_button_type_empty

添加自定义按钮

MiniControllerFragment 支持添加自定义控件按钮, 并非由 SDK 提供,例如“我喜欢”按钮。具体步骤包括:

  1. 使用 @id/cast_button_type_custom (在 MiniControllerFragmentcastControlButtons 属性中)。

  2. 实现 UIControllerUIController 包含 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);
        ...
    }
}

自定义展开的控制器

自定义主题背景

如果展开的控制器的 activity 使用深色主题工具栏,您可以 可以在工具栏上设置主题,以使用浅色文本和浅色图标颜色:

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

选择按钮

展开的控制器的 activity 有 5 个槽位用于显示控件按钮。中间 显示“播放/暂停”切换按钮,且不可配置。其他四个 槽由发送方应用按照从左到右的顺序进行配置。

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

默认情况下,Activity 会显示一个字幕按钮,用于跳转至 “上一项”按钮、“跳至下一项”按钮以及“静音”切换开关 按钮。开发者可以使用 属性 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_emptyCastContext 可以管理生命周期和 此活动的演示

添加自定义按钮

ExpandedControllerActivity 支持添加 SDK 未提供的自定义控件按钮, 例如“我喜欢”按钮。具体步骤包括:

  1. 使用 @id/cast_button_type_custom (在 ExpandedControllerActivitycastControlButtons 属性中)。 然后,您可以使用 getButtonImageViewAt(int) 获取 ImageView 该自定义按钮。

  2. 实现 UIControllerUIController 包含 SDK 在创建状态时调用的方法 投射会话或媒体会话发生变化。您的 UIController 应将 ImageView 作为一个参数, 并根据需要更新其状态。

  3. 为 ExpandControllerActivity 创建子类,然后替换 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>
<ph type="x-smartling-placeholder">
</ph>
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);
        ...
    }
}