Personaliza la IU de Android Sender

Puedes personalizar los widgets de Cast estableciendo los colores, aplicando estilos a los botones, el texto y la miniatura y eligiendo los tipos de botones que quieres mostrar.

Cómo personalizar el tema de una app

En este ejemplo, se crea un estilo de tema personalizado Theme.CastVideosTheme que puedes definir colores personalizados, un estilo introductorio de superposición, un minicontrol y un estilo de control 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 de arriba te permiten definir estilos específicos para superposición introductoria, minicontrol y control expandido como parte de este tema. En las siguientes secciones, se incluyen ejemplos.

Personalizar el 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 de Media Router y declara uno personalizado 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>

setTint se debe usar si la versión de la biblioteca de compatibilidad es posterior a la 26.0.0. Para mayores versiones de la biblioteca de compatibilidad, usa buttonTint en su lugar.

Personalizar el tema de superposición introductorio

El IntroductoryOverlay admite varios atributos de estilo que tu app puede anular en una el tema. En este ejemplo, se muestra cómo anular la apariencia del texto del botón y el 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>

Personalizar minicontrol

Personalizar tema

El MiniControllerFragment admite varios atributos de estilo que tu app puede anular en una el tema. Este ejemplo muestra cómo habilitar la visualización de la imagen en miniatura, para anular la apariencia del texto del subtítulo y del subtítulo, 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 elemento MiniControllerFragment tiene tres espacios que pueden mostrar la imagen del álbum. y dos botones o tres botones de control si la imagen del álbum no se completa.

SLOT  SLOT  SLOT
  1     2     3

De forma predeterminada, el fragmento muestra un botón de activación/pausa. Los desarrolladores pueden usar el atributo castControlButtons para anular los botones que se mostrarán. Los botones de control compatibles 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 fila
@id/cast_button_type_skip_next Salta 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 Adelantar 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

Aquí hay un ejemplo en el que se usaría la imagen del álbum, un botón de activación o 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, un entorno de ejecución se arrojará una excepción. Si no quieres mostrar un botón en un espacio, usa @id/cast_button_type_empty

Agrega botones personalizados

Un MiniControllerFragment admite agregar botones de control personalizados que son no proporcionados por el SDK, como un "Me gusta" . Estos son los pasos:

  1. Especifica un espacio para que contenga un botón personalizado usando @id/cast_button_type_custom en el atributo castControlButtons de MiniControllerFragment.

  2. Implementa una subclase de UIController El UIController contiene métodos que llama el SDK cuando el estado de la sesión de transmisión o multimedia. Tu subclase de UIController debería tomar un ImageView como uno de los parámetros y actualizar su estado según sea necesario.

  3. Subclase MiniControllerFragment, luego, anular onCreateView y llamar getButtonImageViewAt(int) para obtener la ImageView para ese botón personalizado. Luego, llama bindViewToUIController(View, UIController) para asociar la vista con tu UIController

  4. Consulta MediaIntentReceiver en Agregar acciones personalizadas para saber cómo manejar la acción. en el botón personalizado.

    Este es un ejemplo de cómo asociar un botón del espacio 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>
Kotlin
// 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)
        ...
    }
}
Java
// 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 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 las imágenes que quieras usar para dibujar los botones en la 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>

Elegir botones

El elemento Activity del control expandido tiene cinco ranuras en las que se muestran los botones de control. El medio siempre muestra un botón para activar o desactivar la reproducción/pausa y no se puede configurar. Las otras cuatro las ranuras son configurables, de izquierda a derecha, por la app emisora.

SLOT  SLOT  PLAY/PAUSE  SLOT  SLOT
  1     2     BUTTON      3     4

De forma predeterminada, la actividad muestra un botón de subtítulos, una navegación botón del elemento anterior, un botón para pasar al siguiente elemento y un botón de activación para silenciar en estos cuatro espacios, de izquierda a derecha. Los desarrolladores pueden usar el el atributo castControlButtons para anular en qué botones se mostrarán qué ranuras. La lista de botones de control compatibles se define de la siguiente manera: de ID idénticos al tipos de botones para los botones del minicontrol.

Este es un ejemplo que coloca un botón de retroceso en la segunda ranura, una posición de avance en la tercera ranura y dejando la primera y la última 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 generará una excepción de entorno de ejecución una función de este tipo. Si no quieres mostrar un botón en un espacio, usa @id/cast_button_type_empty CastContext puede administrar el ciclo de vida y presentación de esta actividad.

Agrega botones personalizados

Un objeto ExpandedControllerActivity admite agregar botones de control personalizados que no proporciona el SDK. como un pulgar hacia arriba . Estos son los pasos:

  1. Especifica un espacio para que contenga un botón personalizado usando @id/cast_button_type_custom en el atributo castControlButtons de ExpandedControllerActivity. Luego, puedes usar getButtonImageViewAt(int) para obtener el ImageView para ese botón personalizado.

  2. Implementa una subclase de UIController UIController contiene métodos que llama el SDK cuando el estado de la sesión de transmisión o multimedia. Tu subclase de UIController debe tomar un ImageView como uno de los parámetros. y actualiza su estado según sea necesario.

  3. Subclase ExpandedControllerActivity y, luego, anular onCreate y llama getButtonImageViewAt(int) para obtener el objeto View del botón. Luego, llama bindViewToUIController(View, UIController) para asociar la vista con tu UIController personalizado.

  4. Consulta MediaIntentReceiver en Agregar acciones personalizadas sobre cómo controlar la acción de tu botón personalizado.

Este es un ejemplo de cómo asociar un botón del espacio 2 a un UIController llamó a 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>
Kotlin
// 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)
        ...
    }
}
Java
// 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);
        ...
    }
}