Вы можете настраивать виджеты Cast , устанавливая цвета, стили кнопок, текста и эскизов, а также выбирая типы отображаемых кнопок.
Настроить тему приложения
В этом примере создается пользовательский стиль темы Theme.CastVideosTheme
, который может определять пользовательские цвета, начальный стиль наложения, стиль мини-контроллера и стиль расширенного контроллера.
<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>
Последние три строки выше позволяют определить стили, специфичные для вводного наложения, мини-контроллера и расширенного контроллера как часть этой темы. Примеры включены в следующие разделы.
Настроить кнопку трансляции
Чтобы добавить пользовательскую тему mediaRouteTheme
в тему вашего приложения:
<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- ... -->
<item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
</style>
Объявите свою пользовательскую тему Media Router и объявите собственный 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
следует использовать, если версия библиотеки поддержки новее 26.0.0. Для более старых версий библиотеки поддержки используйте вместо этого buttonTint
.
Настройка вводной темы оверлея
Класс IntroductoryOverlay
поддерживает различные атрибуты стиля, которые ваше приложение может переопределить в настраиваемой теме. В этом примере показано, как переопределить внешний вид текста кнопки и заголовка поверх виджета наложения:
<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>
Настроить мини-контроллер
Настроить тему
Класс MiniControllerFragment
поддерживает различные атрибуты стиля, которые ваше приложение может переопределить в настраиваемой теме. В этом примере показано, как включить отображение миниатюры, переопределить внешний вид текста как подзаголовка, так и закрытой подписи, установить цвета и настроить кнопки:
<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>
Выбрать кнопки
MiniControllerFragment
имеет три слота, которые могут отображать обложку альбома, и две кнопки или три кнопки управления, если обложка альбома не заполнена.
SLOT SLOT SLOT
1 2 3
По умолчанию фрагмент показывает кнопку переключения воспроизведения/паузы. Разработчики могут использовать атрибут castControlButtons
, чтобы переопределить отображаемые кнопки. Поддерживаемые кнопки управления определяются как ресурсы ID :
Тип кнопки | Описание |
---|---|
@id/cast_button_type_empty | Не размещайте кнопку в этом слоте |
@id/cast_button_type_custom | Пользовательская кнопка |
@id/cast_button_type_play_pause_toggle | Переключение между воспроизведением и паузой |
@id/cast_button_type_skip_previous | Переходит к предыдущему элементу в очереди |
@id/cast_button_type_skip_next | Переход к следующему элементу в очереди |
@id/cast_button_type_rewind_30_seconds | Перематывает воспроизведение на 30 секунд назад. |
@id/cast_button_type_forward_30_seconds | Пропускает воспроизведение вперед на 30 секунд |
@id/cast_button_type_mute_toggle | Отключает и включает звук приемника |
@id/cast_button_type_closed_caption | Открывает диалоговое окно для выбора текстовых и звуковых дорожек. |
Вот пример, в котором будет использоваться обложка альбома, кнопка переключения воспроизведения/паузы и кнопка перехода вперед в указанном порядке слева направо:
<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">
Предупреждение : этот массив должен содержать ровно три элемента, иначе будет выдано исключение времени выполнения. Если вы не хотите показывать кнопку в слоте, используйте @id/cast_button_type_empty
.
Добавить пользовательские кнопки
MiniControllerFragment
поддерживает добавление настраиваемых кнопок управления, которые не предоставляются пакетом SDK, например кнопку "большой палец вверх". Шаги:
Укажите слот для пользовательской кнопки, используя
@id/cast_button_type_custom
в атрибутеcastControlButtons
MiniControllerFragment
.Реализуйте подкласс
UIController
.UIController
содержит методы, которые вызываются пакетом SDK при изменении состояния сеанса приведения или мультимедийного сеанса. Ваш подклассUIController
должен приниматьImageView
в качестве одного из параметров и обновлять его состояние по мере необходимости.Подкласс
MiniControllerFragment
, затем переопределитеonCreateView
и вызовитеgetButtonImageViewAt(int)
, чтобы получитьImageView
для этой пользовательской кнопки. Затем вызовитеbindViewToUIController(View, UIController)
, чтобы связать представление с вашим пользовательскимUIController
.См.
MediaIntentReceiver
в разделе «Добавление настраиваемых действий» , чтобы узнать, как обрабатывать действие с помощью пользовательской кнопки.Вот пример связывания кнопки в слоте 2 с
UIController
с именем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); ... } }
Настроить расширенный контроллер
Настроить тему
Если действие расширенного контроллера использует панель инструментов темной темы, вы можете установить тему на панели инструментов для использования светлого текста и светлого цвета значка:
<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="castExpandedControllerToolbarStyle">
@style/ThemeOverlay.AppCompat.Dark.ActionBar
</item>
</style>
Вы можете указать свои собственные изображения, которые используются для рисования кнопок на расширенном контроллере:
<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>
Выбрать кнопки
Активность расширенного контроллера имеет пять слотов для отображения кнопок управления. В среднем слоте всегда отображается кнопка переключения воспроизведения/паузы, и его нельзя настроить. Остальные четыре слота настраиваются слева направо приложением-отправителем.
SLOT SLOT PLAY/PAUSE SLOT SLOT
1 2 BUTTON 3 4
По умолчанию действие показывает кнопку скрытых субтитров, кнопку перехода к предыдущему элементу, кнопку перехода к следующему элементу и кнопку отключения звука в этих четырех слотах слева направо. Разработчики могут использовать атрибут castControlButtons
, чтобы переопределить, какие кнопки должны отображаться в каких слотах. Список поддерживаемых кнопок управления определяется как ресурсы ID, идентичные типам кнопок для кнопок мини-контроллера .
Вот пример, который помещает кнопку перемотки назад во второй слот, кнопку перехода вперед в третий слот и оставляет первый и последний слоты пустыми:
// 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>
Массив должен содержать ровно четыре элемента, иначе будет выдано исключение времени выполнения. Если вы не хотите показывать кнопку в слоте, используйте @id/cast_button_type_empty
. CastContext
может управлять жизненным циклом и представлением этого действия.
Добавить пользовательские кнопки
ExpandedControllerActivity
поддерживает добавление настраиваемых кнопок управления, которые не предоставляются пакетом SDK, например кнопку "большой палец вверх". Шаги:
Укажите слот для пользовательской кнопки, используя
@id/cast_button_type_custom
в атрибутеcastControlButtons
ExpandedControllerActivity
. Затем вы можете использоватьgetButtonImageViewAt(int)
для полученияImageView
для этой пользовательской кнопки.Реализуйте подкласс
UIController
.UIController
содержит методы, которые вызываются пакетом SDK при изменении состояния сеанса трансляции или сеанса мультимедиа. Ваш подклассUIController
должен приниматьImageView
в качестве одного из параметров и обновлять его состояние по мере необходимости.Подкласс ExpandedControllerActivity, затем переопределите
onCreate
и вызовитеgetButtonImageViewAt(int)
, чтобы получить объект представления кнопки. Затем вызовитеbindViewToUIController(View, UIController)
, чтобы связать представление с вашим пользовательскимUIController
.См.
MediaIntentReceiver
в разделе «Добавление настраиваемых действий» , чтобы узнать, как обрабатывать действие с помощью пользовательской кнопки.
Вот пример связывания кнопки в слоте 2 с UIController
с именем 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); ... } }