Personalizar el tema de la app
En este ejemplo, se crea un estilo de tema personalizado Theme.CastVideosTheme que puede definir colores personalizados, un estilo de superposición introductorio, un estilo de mini controlador y un estilo de controlador expandido.
<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>
Las últimas tres líneas anteriores te permiten definir estilos específicos para la superposición introductoria, el mini controlador y el controlador expandido como parte de este tema. En las siguientes secciones, se incluyen ejemplos.
Personalizar el botón de Cast
Para agregar un mediaRouteTheme personalizado al tema de tu app, haz lo siguiente:
<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- ... -->
<item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
</style>
Declara tu tema personalizado de Media Router y declara un mediaRouteButtonStyle personalizado:
<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
Se debe usar si la versión de la biblioteca de compatibilidad es más reciente que 26.0.0. Para versiones anteriores de la biblioteca de compatibilidad, usa buttonTinten su lugar.
Personalizar el tema de la superposición introductoria
La clase
IntroductoryOverlay
admite varios atributos de estilo que tu app puede anular en un tema
personalizado. En este ejemplo, se muestra cómo anular la apariencia del texto del botón y el título sobre el widget de superposición:
<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>
Personalizar el mini controlador
Personalizar tema
La
MiniControllerFragment
clase admite varios atributos de estilo que tu app puede anular en un tema
personalizado. En este ejemplo, se muestra cómo habilitar la visualización de la imagen en miniatura, anular la apariencia del texto del subtítulo y los subtítulos opcionales, configurar los colores y personalizar los botones:
<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>
Elegir botones
Un MiniControllerFragment tiene tres ranuras que pueden mostrar la imagen del álbum y dos botones, o tres botones de control si la imagen del álbum no está propagada.
SLOT SLOT SLOT
1 2 3
De forma predeterminada, el fragmento muestra un botón de alternancia de reproducción/pausa. Los desarrolladores pueden usar el atributo castControlButtons para anular qué botones mostrar.
Los botones de control admitidos se definen como
recursos de ID:
| Tipo de botón | Descripción |
|---|---|
@id/cast_button_type_empty |
No coloques un botón en esta ranura |
@id/cast_button_type_custom |
Botón personalizado |
@id/cast_button_type_play_pause_toggle |
Alterna entre reproducción y pausa |
@id/cast_button_type_skip_previous |
Salta al elemento anterior de la cola |
@id/cast_button_type_skip_next |
Salta al siguiente elemento de la cola |
@id/cast_button_type_rewind_30_seconds |
Retrocede la reproducción 30 segundos |
@id/cast_button_type_forward_30_seconds |
Avanza la reproducción 30 segundos |
@id/cast_button_type_mute_toggle |
Silencia y activa el sonido del receptor |
@id/cast_button_type_closed_caption |
Abre un diálogo para seleccionar pistas de texto y audio |
Este es un ejemplo que usaría la imagen del álbum, un botón de activación de reproducción/pausa y un botón de avance rápido en ese orden de izquierda a derecha:
<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">
Advertencia: Este array debe contener exactamente tres elementos. De lo contrario, se generará una excepción en el tiempo de ejecución
. Si no quieres mostrar un botón en una ranura, usa @id/cast_button_type_empty.
Agregar botones personalizados
Un MiniControllerFragment admite la adición de botones de control personalizados que no proporciona el SDK, como un botón "Me gusta". Estos son los pasos:
Especifica una ranura para que contenga un botón personalizado con
@id/cast_button_type_customen elcastControlButtonsatributo de laMiniControllerFragment.Implementa una subclase de
UIController. ElUIControllercontiene métodos que el SDK llama cuando cambia el estado de la sesión de Cast o de la sesión de contenido multimedia. Tu subclase deUIControllerdebe tomar unImageViewcomo uno de los parámetros y actualizar su estado según sea necesario.Subclase
MiniControllerFragment, luego anulaonCreateViewy llamagetButtonImageViewAt(int)para obtener elImageViewde ese botón personalizado. Luego, llama abindViewToUIController(View, UIController)para asociar la vista con tuUIControllerpersonalizado.Consulta
MediaIntentReceiveren Cómo agregar acciones personalizadas para obtener información sobre cómo controlar la acción de tu botón personalizado.Este es un ejemplo de cómo asociar un botón en la ranura 2 a un
UIControllerllamadoMyCustomUIController:
// 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); ... } }
Personalizar el controlador expandido
Personalizar tema
Si la Activity de un controlador expandido usa una barra de herramientas de tema oscuro, puedes configurar un tema en la barra de herramientas para usar texto claro y un color de ícono claro:
<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="castExpandedControllerToolbarStyle">
@style/ThemeOverlay.AppCompat.Dark.ActionBar
</item>
</style>
Puedes especificar tus propias imágenes que se usan para dibujar los botones en el controlador expandido:
<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>
Elegir botones
La actividad del controlador expandido tiene cinco ranuras para mostrar botones de control. La ranura central siempre muestra un botón de alternancia de reproducción/pausa y no se puede configurar. Las otras cuatro ranuras se pueden configurar, de izquierda a derecha, con la app del remitente.
SLOT SLOT PLAY/PAUSE SLOT SLOT
1 2 BUTTON 3 4
De forma predeterminada, la actividad muestra un botón de subtítulos opcionales, un botón para saltar al elemento anterior, un botón para saltar al siguiente elemento y un botón de alternancia de silencio en estas cuatro ranuras, de izquierda a derecha. Los desarrolladores pueden usar el atributo castControlButtons para anular qué botones mostrar en qué ranuras. La lista de botones de control admitidos se define como
recursos de ID idénticos a los
tipos de botones para los botones del mini controlador.
Este es un ejemplo que coloca un botón de retroceso en la segunda ranura, un botón de avance rápido en la tercera ranura y deja vacías la primera y la última ranura:
// 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>
El array debe contener exactamente cuatro elementos. De lo contrario, se generará una excepción en el tiempo de ejecución. Si no quieres mostrar un botón en una ranura, usa @id/cast_button_type_empty. CastContext puede administrar el ciclo de vida y la presentación de esta actividad.
Agregar botones personalizados
Un ExpandedControllerActivity admite la adición de botones de control personalizados que no proporciona el SDK,
como un botón "Me gusta". Estos son los pasos:
Especifica una ranura para que contenga un botón personalizado con
@id/cast_button_type_customen elcastControlButtonsatributo de laExpandedControllerActivity. Luego, puedes usargetButtonImageViewAt(int)para obtener elImageViewde ese botón personalizado.Implementa una subclase de
UIController.UIControllercontiene métodos que el SDK llama cuando cambia el estado de la sesión de Cast o de la sesión de contenido multimedia. Tu subclase deUIControllerdebe tomar unImageViewcomo uno de los parámetros y actualizar su estado según sea necesario.Subclase ExpandedControllerActivity, luego anula
onCreatey llama agetButtonImageViewAt(int)para obtener el objeto de vista del botón. Luego, llama abindViewToUIController(View, UIController)para asociar la vista con tuUIControllerpersonalizado.Consulta
MediaIntentReceiveren Cómo agregar acciones personalizadas para obtener información sobre cómo controlar la acción de tu botón personalizado.
Este es un ejemplo de cómo asociar un botón en la ranura 2 a un
UIController llamado 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); ... } }