Vous pouvez personnaliser les widgets Cast en définissant les couleurs des boutons, le texte et l'apparence des vignettes, et en choisissant les types de boutons à afficher.
Personnaliser le thème de l'application
Cet exemple crée un style de thème personnalisé Theme.CastVideosTheme
qui peut définir des couleurs personnalisées, un style de superposition d'introduction, un style de mini-télécommande et un style de manette étendu.
<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>
Les trois dernières lignes ci-dessus vous permettent de définir des styles spécifiques à la superposition d'introduction, à la mini-télécommande et au contrôleur étendu dans le cadre de ce thème. Vous trouverez des exemples dans les sections suivantes.
Personnaliser l'icône Cast
Pour ajouter un mediaRouteTheme
personnalisé au thème de votre application:
<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- ... -->
<item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
</style>
Déclarez votre thème Media Router personnalisé et déclarez un mediaRouteButtonStyle
personnalisé:
<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
doit être utilisé si la version de la bibliothèque Support est plus récente que la version 26.0.0. Pour les anciennes versions de la bibliothèque Support, utilisez plutôt buttonTint
.
Personnaliser le thème de présentation de la superposition
La classe IntroductoryOverlay
accepte différents attributs de style que votre application peut remplacer dans un thème personnalisé. Cet exemple montre comment remplacer l'apparence du texte du bouton et du titre sur le widget de superposition:
<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>
Personnaliser la mini-télécommande
Personnaliser le thème
La classe MiniControllerFragment
accepte différents attributs de style que votre application peut remplacer dans un thème personnalisé. Cet exemple montre comment activer l'affichage de la vignette, remplacer l'apparence du texte du sous-titre et des sous-titres, définir les couleurs et personnaliser les boutons:
<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>
Choisir des boutons
Un élément MiniControllerFragment
comporte trois emplacements permettant d'afficher la pochette de l'album et deux boutons, ou trois boutons de commande si l'image n'est pas renseignée.
SLOT SLOT SLOT
1 2 3
Par défaut, le fragment affiche un bouton d'activation/de désactivation de la lecture/pause. Les développeurs peuvent utiliser l'attribut castControlButtons
pour ignorer les boutons à afficher.
Les boutons de commande compatibles sont définis en tant que ressources d'ID:
Type de bouton | Description |
---|---|
@id/cast_button_type_empty |
Ne pas placer de bouton dans cet emplacement |
@id/cast_button_type_custom |
Bouton personnalisé |
@id/cast_button_type_play_pause_toggle |
Alterne entre lecture et pause |
@id/cast_button_type_skip_previous |
Passer à l'élément précédent dans la file d'attente |
@id/cast_button_type_skip_next |
Passer à l'élément suivant dans la file d'attente |
@id/cast_button_type_rewind_30_seconds |
Revenir en arrière de 30 secondes dans la lecture |
@id/cast_button_type_forward_30_seconds |
Avance de 30 secondes dans la lecture |
@id/cast_button_type_mute_toggle |
Coupe et réactive le son du destinataire |
@id/cast_button_type_closed_caption |
Ouvre une boîte de dialogue permettant de sélectionner du texte et des pistes audio |
Voici un exemple d'utilisation de la pochette de l'album, d'un bouton d'activation/de désactivation de la lecture/pause et d'un bouton d'avance rapide, dans cet ordre de gauche à droite:
<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">
Avertissement: Ce tableau doit contenir exactement trois éléments, sans quoi une exception d'exécution sera générée. Si vous ne souhaitez pas afficher de bouton dans un emplacement, utilisez @id/cast_button_type_empty
.
Ajouter des boutons personnalisés
Un MiniControllerFragment
permet d'ajouter des boutons de commande personnalisés qui ne sont pas fournis par le SDK, tels qu'un bouton "J'aime". Voici la procédure à suivre :
Spécifiez un emplacement pour accueillir un bouton personnalisé à l'aide de
@id/cast_button_type_custom
dans l'attributcastControlButtons
deMiniControllerFragment
.Implémentez une sous-classe de
UIController
.UIController
contient les méthodes appelées par le SDK lorsque l'état de la session de diffusion ou de la session multimédia change. Votre sous-classe deUIController
doit utiliserImageView
comme paramètre et mettre à jour son état si nécessaire.Sous-classe
MiniControllerFragment
, remplacezonCreateView
et appelezgetButtonImageViewAt(int)
pour obtenir leImageView
de ce bouton personnalisé. Appelez ensuitebindViewToUIController(View, UIController)
pour associer la vue à votreUIController
personnalisé.Pour savoir comment gérer l'action à partir de votre bouton personnalisé, consultez
MediaIntentReceiver
dans Ajouter des actions personnalisées.Voici un exemple d'association d'un bouton situé au niveau de l'emplacement 2 à un élément
UIController
appelé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>
// 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); ... } }
Personnaliser la télécommande agrandie
Personnaliser le thème
Si l'activité d'une manette développée utilise une barre d'outils de thème sombre, vous pouvez définir un thème sur la barre d'outils pour utiliser du texte clair et une couleur d'icône claire:
<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="castExpandedControllerToolbarStyle">
@style/ThemeOverlay.AppCompat.Dark.ActionBar
</item>
</style>
Vous pouvez spécifier vos propres images pour dessiner les boutons du contrôleur développé:
<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>
Choisir des boutons
Le menu d'activité de la manette développée comporte cinq emplacements permettant d'afficher des boutons de commande. L'emplacement du milieu comporte toujours un bouton d'activation/de désactivation de la lecture/pause et n'est pas configurable. Les quatre autres emplacements peuvent être configurés, de gauche à droite, par l'application émettrice.
SLOT SLOT PLAY/PAUSE SLOT SLOT
1 2 BUTTON 3 4
Par défaut, l'activité affiche un bouton de sous-titres, un bouton pour passer à l'élément précédent, un bouton pour passer à l'élément suivant et un bouton d'activation de coupure du son dans ces quatre emplacements, de gauche à droite. Les développeurs peuvent utiliser l'attribut castControlButtons
pour ignorer les boutons à afficher dans quels emplacements. La liste des boutons de commande compatibles est définie comme des ressources d'ID identiques aux types de boutons pour les boutons de mini-télécommande.
Dans l'exemple ci-dessous, un bouton de retour arrière est placé au deuxième emplacement, un bouton "Avancer" au troisième emplacement, et les premier et dernier emplacements sont vides:
// 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>
Le tableau doit contenir exactement quatre éléments, sans quoi une exception d'exécution sera générée. Si vous ne souhaitez pas afficher de bouton dans un emplacement, utilisez @id/cast_button_type_empty
. CastContext
peut gérer le cycle de vie et la présentation de cette activité.
Ajouter des boutons personnalisés
Un ExpandedControllerActivity
permet d'ajouter des boutons de commande personnalisés qui ne sont pas fournis par le SDK, tels qu'un bouton "J'aime". Voici la procédure à suivre :
Spécifiez un emplacement pour accueillir un bouton personnalisé à l'aide de
@id/cast_button_type_custom
dans l'attributcastControlButtons
deExpandedControllerActivity
. Vous pouvez ensuite utilisergetButtonImageViewAt(int)
afin d'obtenir laImageView
pour ce bouton personnalisé.Implémentez une sous-classe de
UIController
.UIController
contient les méthodes appelées par le SDK lorsque l'état de la session de diffusion ou de la session multimédia change. Votre sous-classe deUIController
doit utiliserImageView
comme paramètre et mettre à jour son état si nécessaire.Sous-classe ExtendControllerActivity, puis remplacez
onCreate
et appelezgetButtonImageViewAt(int)
pour obtenir l'objet de vue du bouton. Appelez ensuitebindViewToUIController(View, UIController)
pour associer la vue à votreUIController
personnalisé.Pour savoir comment gérer l'action à partir de votre bouton personnalisé, consultez
MediaIntentReceiver
dans Ajouter des actions personnalisées.
Voici un exemple d'association d'un bouton au niveau de l'emplacement 2 à une UIController
appelée 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>
// 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); ... } }