Para personalizar los widgets de transmisión, configura los colores, diseña los botones, el texto y la miniatura, y elige los tipos de botones que se mostrarán.
Personaliza 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 minicontrol 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 tres líneas anteriores te permiten definir estilos específicos para la superposición introductoria, el minicontrolador y el controlador expandido como parte de este tema. A continuación, se incluyen ejemplos.
Personalizar botón para transmitir
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 del router de contenido multimedia 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>
Se debe usar setTint
si la versión de la biblioteca de compatibilidad es posterior a 26.0.0. Para las versiones anteriores de bibliotecas de compatibilidad, usa buttonTint
.
Personalizar el tema de 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 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 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, a fin de anular el aspecto del texto del subtítulo y de 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>
Elegir botones
Un objeto MiniControllerFragment
tiene tres ranuras que pueden mostrar la imagen del álbum y dos botones, o tres botones de control si no se propaga.
SLOT SLOT SLOT
1 2 3
De forma predeterminada, el fragmento muestra un botón para activar o desactivar la reproducción. Los desarrolladores pueden usar el atributo castControlButtons
para anular los botones que se mostrarán.
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 este espacio |
@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 |
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 |
Avanzar la reproducción 30 segundos |
@id/cast_button_type_mute_toggle |
Silencia y deja de silenciar el receptor. |
@id/cast_button_type_closed_caption |
Abre un cuadro de diálogo para seleccionar pistas de texto y audio |
A continuación, te mostramos un ejemplo que usaría la portada del álbum, un botón de activación para pausar/reproducir 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 entorno de ejecución. Si no quieres mostrar un botón en una ranura, usa @id/cast_button_type_empty
.
Agrega 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
deMiniControllerFragment
.Implementa una subclase de
UIController
. ElUIController
contiene métodos a los que el SDK llama cuando cambia el estado de la sesión de transmisión o la sesión multimedia. La subclase deUIController
debe tomar un elementoImageView
como uno de los parámetros y actualizar su estado según sea necesario.Crea una subclase
MiniControllerFragment
y, 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 Agrega acciones personalizadas para conocer cómo controlar la acción desde el botón personalizado.A continuación, se muestra un ejemplo para asociar un botón de la ranura 2 a un objeto
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); ... } }
Personalizar el control expandido
Personalizar tema
Si la actividad de un control expandido usa una barra de herramientas de Tema oscuro, puedes establecer un tema en la barra de herramientas para usar texto claro y el color de un í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 los botones de control. La ranura del medio siempre muestra un botón de activación para reproducir y pausar, y no se puede configurar. La app emisora puede configurar las otras cuatro ranuras de izquierda a derecha.
SLOT SLOT PLAY/PAUSE SLOT SLOT
1 2 BUTTON 3 4
De forma predeterminada, el objeto Activity muestra un botón de subtítulos, un botón de omisión para ir al elemento anterior, un botón para ir al siguiente elemento y un botón para activar o desactivar el sonido en estos cuatro espacios de izquierda a derecha. Los desarrolladores pueden usar el atributo castControlButtons
para anular qué botones mostrar en cada ranura. La lista de botones de control admitidos se define como recursos de ID idénticos a los tipos de botones para los botones del minicontrolador.
A continuación, se muestra un ejemplo en el que se coloca un botón de retroceso en el segundo espacio, un botón para adelantar en el tercero y dejar las primeras y las últimas ranuras vacías:
// 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 arrojará una excepción de entorno 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.
Agrega botones personalizados
Un objeto ExpandedControllerActivity
admite que se agreguen 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
deExpandedControllerActivity
. Luego, puedes usargetButtonImageViewAt(int)
a fin de obtener elImageView
para ese botón personalizado.Implementa una subclase de
UIController
.UIController
contiene métodos a los que el SDK llama cuando cambia el estado de la sesión de transmisión o la sesión multimedia. La subclase deUIController
debe tomar unImageView
como uno de los parámetros y actualizar su estado según sea necesario.Crea una subclase de ExpandedControllerActivity, 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 Agrega acciones personalizadas para administrar la acción desde tu botón personalizado.
A continuación, se muestra un ejemplo de cómo asociar un botón de 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); ... } }