色を設定したり、ボタン、テキスト、サムネイルの外観のスタイルを設定したり、表示するボタンの種類を選択したりして、キャスト ウィジェットをカスタマイズできます。
アプリのテーマをカスタマイズする
この例では、カスタムテーマ スタイル 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>
カスタム メディア ルーターのテーマを宣言し、カスタム 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 には、アルバム アートと 2 つのボタンを表示できる 3 つのスロットがあります。アルバム アートが設定されていない場合は、3 つのコントロール ボタンを表示できます。
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">
警告: この配列には 3 つの項目を含める必要があります。そうしないと、実行時例外がスローされます。スロットにボタンを表示しない場合は、@id/cast_button_type_empty を使用します。
カスタムボタンを追加する
MiniControllerFragment は、SDK で提供されていないカスタム コントロール ボタン(高評価ボタンなど)の追加をサポートしています。ステップは次のとおりです。
- MiniControllerFragmentの- castControlButtons属性で- @id/cast_button_type_customを使用して、カスタムボタンを含むスロットを指定します。
- UIControllerのサブクラスを実装します。- UIControllerには、キャスト セッションまたはメディア セッションの状態が変化したときに SDK によって呼び出されるメソッドが含まれています。- UIControllerのサブクラスは、パラメータの 1 つとして- 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); ... } }
拡張コントローラをカスタマイズする
テーマのカスタマイズ
展開されたコントローラの 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 つのスロットがあります。中央のスロットには常に再生/一時停止の切り替えボタンが表示され、構成できません。他の 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 で提供されていないカスタム コントロール ボタン(「高評価」ボタンなど)の追加をサポートします。ステップは次のとおりです。
- ExpandedControllerActivityの- castControlButtons属性で- @id/cast_button_type_customを使用して、カスタムボタンを含むスロットを指定します。その後、- getButtonImageViewAt(int)を使用して、そのカスタムボタンの- ImageViewを取得できます。
- UIControllerのサブクラスを実装します。- UIControllerには、キャスト セッションまたはメディア セッションの状態が変化したときに SDK によって呼び出されるメソッドが含まれています。- UIControllerのサブクラスは、パラメータの 1 つとして- ImageViewを受け取り、必要に応じて状態を更新する必要があります。
- ExpandedControllerActivity をサブクラス化し、 - onCreateをオーバーライドして- getButtonImageViewAt(int)を呼び出し、ボタンのビュー オブジェクトを取得します。次に、- 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); ... } }