Puedes personalizar los widgets de Cast configurando los colores, el estilo de los botones, el texto y la apariencia de la miniatura, y seleccionando los tipos de botones que quieres mostrar.
Personaliza el tema de la app
En este ejemplo, se crea un diseño de tema personalizado Theme.CastVideosTheme
que puede definir colores personalizados, un diseño de superposición introductoria, un diseño de controlador pequeño y un diseño 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 capa superpuesta introductoria, el controlador mini y el controlador expandido como parte de este tema. En las siguientes secciones, se incluyen ejemplos.
Personaliza 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 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 posterior a la 26.0.0. Para versiones anteriores de la biblioteca de compatibilidad, usa buttonTint
en su lugar.
Personaliza 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 del título en 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>
Personaliza el minicontrol
Personalizar tema
La clase MiniControllerFragment
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, establecer 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>
Elige botones
Un MiniControllerFragment
tiene tres ranuras que pueden mostrar la carátula del álbum y dos botones, o tres botones de control si no se completa la carátula del álbum.
SLOT SLOT SLOT
1 2 3
De forma predeterminada, el fragmento muestra un botón de activación/desactivación para reproducir o pausar. Los desarrolladores pueden usar el atributo castControlButtons
para anular los botones que se muestran.
Los botones de control admitidos se definen como recursos de ID:
Tipo de botón | Descripción |
---|---|
@id/cast_button_type_empty |
No coloque un botón en esta ranura |
@id/cast_button_type_custom |
Botón personalizado |
@id/cast_button_type_play_pause_toggle |
Alterna entre la reproducción y la pausa |
@id/cast_button_type_skip_previous |
Ir al elemento anterior de la fila |
@id/cast_button_type_skip_next |
Ir al siguiente elemento de la fila |
@id/cast_button_type_rewind_30_seconds |
Retrocede la reproducción 30 segundos. |
@id/cast_button_type_forward_30_seconds |
Adelanta 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 |
A continuación, se muestra un ejemplo que usaría la portada del álbum, un botón de activación para reproducir o pausar, y un botón para adelantar, 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 arrojará una excepción de tiempo de ejecución. Si no quieres mostrar un botón en una ranura, usa @id/cast_button_type_empty
.
Cómo agregar botones personalizados
Un MiniControllerFragment
admite la adición de botones de control personalizados que no proporciona el SDK, como un botón de "me gusta". Estos son los pasos:
Especifica una ranura para que contenga un botón personalizado con
@id/cast_button_type_custom
en el atributocastControlButtons
delMiniControllerFragment
.Implementa una subclase de
UIController
. ElUIController
contiene métodos a los que llama el SDK cuando cambia el estado de la sesión de transmisión o de la sesión multimedia. Tu subclase deUIController
debe tomar unImageView
como uno de los parámetros y actualizar su estado según sea necesario.Crea una subclase de
MiniControllerFragment
, luego anulaonCreateView
y llama agetButtonImageViewAt(int)
para obtener elImageView
de ese botón personalizado. Luego, llama abindViewToUIController(View, UIController)
para asociar la vista con tuUIController
personalizado.Consulta
MediaIntentReceiver
en Cómo agregar acciones personalizadas para saber cómo controlar la acción desde tu botón personalizado.Este es un ejemplo de cómo asociar un botón en la ranura 2 a un
UIController
llamadoMyCustomUIController
:
// 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); ... } }
Cómo personalizar el control expandido
Personalizar tema
Si la actividad de un controlador expandido usa una barra de herramientas con tema oscuro, puedes establecer 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 control 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>
Elige botones
La actividad del control expandido tiene cinco ranuras para mostrar botones de control. La ranura central siempre muestra un botón de activación o desactivación de reproducción y no se puede configurar. Los otros cuatro espacios 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, un botón para omitir el elemento anterior, un botón para omitir el elemento siguiente y un botón de activación o desactivación del silencio en estas cuatro ranuras, de izquierda a derecha. Los desarrolladores pueden usar el atributo castControlButtons
para anular qué botones se muestran 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 controlador pequeño.
Este es un ejemplo que coloca un botón de retroceder en la segunda ranura, un botón de adelantar 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 de 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.
Cómo agregar botones personalizados
Un objeto ExpandedControllerActivity
admite la adición de botones de control personalizados que no proporciona el SDK, como un botón de "me gusta". Estos son los pasos:
Especifica una ranura para que contenga un botón personalizado con
@id/cast_button_type_custom
en el atributocastControlButtons
delExpandedControllerActivity
. Luego, puedes usargetButtonImageViewAt(int)
para obtener elImageView
de ese botón personalizado.Implementa una subclase de
UIController
.UIController
contiene métodos a los que llama el SDK cuando cambia el estado de la sesión de transmisión o de la sesión de medios. Tu subclase deUIController
debe tomar unImageView
como uno de los parámetros y actualizar su estado según sea necesario.Crea una subclase de ExpandedControllerActivity y, luego, anula
onCreate
y llama agetButtonImageViewAt(int)
para obtener el objeto de vista del botón. Luego, llama abindViewToUIController(View, UIController)
para asociar la vista con tuUIController
personalizado.Consulta
MediaIntentReceiver
en Cómo agregar acciones personalizadas para saber cómo controlar la acción desde tu botón personalizado.
Este es un ejemplo de cómo asociar un botón en la ranura 2 a un objeto 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); ... } }