Вы можете настроить виджеты 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>
Если версия библиотеки поддержки новее, чем 26.0.0, используйте setTint. Для более ранних версий библиотеки поддержки используйте 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/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); ... } }
Настроить развернутый контроллер
Настройте тему
Если в Activity расширенного контроллера используется панель инструментов с тёмной темой, вы можете задать для нее тему со светлым текстом и светлым цветом значков:
<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>
Выбрать кнопки
В Activity развернутого контроллера есть пять слотов для кнопок управления. В среднем слоте всегда показывается переключатель воспроизведения/паузы, и его нельзя настроить. Остальные четыре слота настраиваются слева направо приложением-отправителем.
SLOT SLOT PLAY/PAUSE SLOT SLOT
1 2 BUTTON 3 4
По умолчанию в этих четырех слотах слева направо отображаются кнопка субтитров, кнопка перехода к предыдущему элементу, кнопка перехода к следующему элементу и кнопка отключения звука. Разработчики могут использовать атрибут castControlButtons, чтобы переопределить, какие кнопки должны показываться в каких слотах. Список поддерживаемых кнопок управления определяется как ресурсы идентификаторов, идентичные типам кнопок для мини-контроллера.
В примере ниже кнопка перемотки назад находится во втором слоте, а кнопка перемотки вперед – в третьем. Первый и последний слоты остаются пустыми.
// 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); ... } }