Widżety przesyłania możesz dostosować, ustawiając kolory, styl przycisków, tekstu i miniatur, a także wybierając typy przycisków, które mają się wyświetlać.
Dostosowywanie motywu aplikacji
W tym przykładzie tworzymy styl motywu niestandardowego Theme.CastVideosTheme
, który może definiować niestandardowe kolory, styl wprowadzającego nakładki, styl sterowania mini oraz styl sterowania rozszerzonego.
<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>
Ostatnie 3 wiersze powyżej umożliwiają zdefiniowanie stylów dotyczących wprowadzającego nakładki, sterownika mini i rozwiniętego sterownika w ramach tego motywu. Przykłady znajdziesz w następnych sekcjach.
Dostosowywanie przycisku przesyłania
Aby dodać niestandardowy mediaRouteTheme
do motywu aplikacji:
<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- ... -->
<item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
</style>
Zadeklaruj niestandardowy motyw Media Router i niestandardowy 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
należy użyć, jeśli wersja biblioteki pomocniczej jest nowsza niż 26.0.0. W przypadku starszych wersji biblioteki pomocy użyj zamiast tego funkcji buttonTint
.
Dostosowywanie motywu nakładki powitalnej
Klasa IntroductoryOverlay
obsługuje różne atrybuty stylu, które aplikacja może zastąpić w ramach niestandardowego motywu. Ten przykład pokazuje, jak zastąpić wygląd tekstu przycisku i tytułu w widżecie nakładki:
<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>
Dostosowywanie minikontrolera
Dostosowanie motywu
Klasa MiniControllerFragment
obsługuje różne atrybuty stylu, które aplikacja może zastąpić w ramach niestandardowego motywu. Ten przykład pokazuje, jak włączyć wyświetlanie miniatury, aby zastąpić wygląd tekstu zarówno nagłówka, jak i napisów, ustawić kolory oraz dostosować przyciski:
<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>
Wybierz przyciski
Element MiniControllerFragment
ma 3 miejsca, w których można wyświetlić okładkę albumu, oraz 2 przyciski. Jeśli okładka albumu nie jest wypełniona, element ma 3 przyciski.
SLOT SLOT SLOT
1 2 3
Domyślnie fragment zawiera przycisk odtwarzania/wstrzymywania. Programiści mogą użyć atrybutu castControlButtons
, aby zastąpić przyciski, które mają się wyświetlać.
Obsługiwane przyciski sterujące są zdefiniowane jako zasoby identyfikatorów:
Typ przycisku | Opis |
---|---|
@id/cast_button_type_empty |
Nie umieszczaj w tym miejscu przycisku |
@id/cast_button_type_custom |
Przycisk niestandardowy |
@id/cast_button_type_play_pause_toggle |
Przełącza między odtwarzaniem a wstrzymaniem. |
@id/cast_button_type_skip_previous |
Przechodzi do poprzedniego elementu w kolejce. |
@id/cast_button_type_skip_next |
Przechodzi do następnego elementu w kolejce. |
@id/cast_button_type_rewind_30_seconds |
przewija odtwarzanie o 30 sekund, |
@id/cast_button_type_forward_30_seconds |
przewinięcie odtwarzania do przodu o 30 sekund, |
@id/cast_button_type_mute_toggle |
wycisza i włącza mikrofon odbiornika. |
@id/cast_button_type_closed_caption |
Otwiera okno, w którym można wybrać tekst i ścieżki audio |
Oto przykład, w którym od lewej do prawej strony użyto okładki albumu, przycisku odtwarzania/wstrzymywania i przycisku przewijania do przodu:
<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">
Ostrzeżenie: tablica musi zawierać dokładnie 3 elementy, w przeciwnym razie zostanie rzucony wyjątek czasu wykonywania. Jeśli nie chcesz wyświetlać przycisku w miejscu, użyj @id/cast_button_type_empty
.
Dodawanie przycisków niestandardowych
MiniControllerFragment
obsługuje dodawanie niestandardowych przycisków sterowania, które nie są udostępniane przez pakiet SDK, takich jak przycisk „kciuk w górę”. Kroki:
W atrybucie
castControlButtons
elementuMiniControllerFragment
wskaż slot, który ma zawierać przycisk niestandardowy, używając do tego parametru@id/cast_button_type_custom
.Zaimplementuj podklasę funkcji
UIController
. ObiektUIController
zawiera metody wywoływane przez pakiet SDK, gdy zmienia się stan sesji przesyłania lub sesji multimediów. Podklasa klasyUIController
powinna przyjmować jako jeden z parametrów obiektImageView
i w razie potrzeby aktualizować jego stan.Utwórz podklasę
MiniControllerFragment
, a następnie zastąpij ją parametremonCreateView
i wywołaj ją parametremgetButtonImageViewAt(int)
, aby uzyskać parametrImageView
dla tego niestandardowego przycisku. Następnie wywołaj funkcjębindViewToUIController(View, UIController)
, aby powiązać widok z widokiem niestandardowymUIController
.Informacje o tym, jak obsługiwać działanie z niestandardowego przycisku, znajdziesz w sekcji Dodawanie działań niestandardowych (
MediaIntentReceiver
).Oto przykład powiązania przycisku w miejscu 2 z elementem
UIController
o nazwieMyCustomUIController
:
// 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); ... } }
Dostosowywanie rozszerzonego kontrolera
Dostosowanie motywu
Jeśli w rozwiniętym kontrolerze w sekcji Aktywność jest używany pasek narzędzi w ciemnym motywie, możesz ustawić motyw na pasku narzędzi, aby używać jasnego tekstu i jasnych kolorów ikon:
<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="castExpandedControllerToolbarStyle">
@style/ThemeOverlay.AppCompat.Dark.ActionBar
</item>
</style>
Możesz podać własne obrazy, które będą używane do rysowania przycisków na rozszerzonym kontrolerze:
<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>
Wybierz przyciski
Aktywność rozszerzonego kontrolera ma 5 miejsc na przyciski sterujące. W środkowym slocie zawsze wyświetla się przycisk odtwarzania/pauzowania i nie można go konfigurować. Pozostałe 4 miejsca są konfigurowalne od lewej do prawej przez aplikację nadawcy.
SLOT SLOT PLAY/PAUSE SLOT SLOT
1 2 BUTTON 3 4
Domyślnie w tych 4 miejscach od lewej do prawej wyświetlają się przycisk napisów, przycisk pominięcia poprzedniego elementu, przycisk pominięcia następnego elementu oraz przycisk wyciszenia. Deweloperzy mogą użyć atrybutu castControlButtons
, aby zastąpić przyciski wyświetlane w danych slotach. Lista obsługiwanych przycisków sterujących jest definiowana jako identyfikatory zasobów identyczne z typami przycisków w przypadku mini kontrolerów.
Oto przykład, w którym w drugim polu znajduje się przycisk przewijania wstecz, w trzecim polu przycisk przewijania do przodu, a pierwsze i ostatnie pole pozostają puste:
// 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>
Tablica musi zawierać dokładnie 4 elementy, w przeciwnym razie zostanie rzucony wyjątek czasu wykonywania. Jeśli nie chcesz wyświetlać przycisku w miejscu, użyj @id/cast_button_type_empty
. CastContext
może zarządzać cyklem życia i prezentacją tej aktywności.
Dodawanie przycisków niestandardowych
ExpandedControllerActivity
obsługuje dodawanie niestandardowych przycisków sterowania, które nie są udostępniane przez pakiet SDK,
takich jak przycisk „kciuk w górę”. Kroki:
W atrybucie
castControlButtons
elementuExpandedControllerActivity
wskaż slot, który ma zawierać przycisk niestandardowy, używając do tego parametru@id/cast_button_type_custom
. Następnie możesz użyć zmiennejgetButtonImageViewAt(int)
, aby uzyskać wartość zmiennejImageView
, która odpowiada temu niestandardowemu przyciskowi.Zaimplementuj podklasę funkcji
UIController
.UIController
zawiera metody wywoływane przez pakiet SDK, gdy zmienia się stan sesji przesyłania lub sesji multimediów. PodklasaUIController
powinna przyjmowaćImageView
jako jeden z parametrów i w razie potrzeby aktualizować jej stan.Utwórz podklasę ExpandedControllerActivity, a potem zastąpij ją parametrem
onCreate
i wywołaj funkcjęgetButtonImageViewAt(int)
, aby uzyskać obiekt widoku przycisku. Następnie wywołaj funkcjębindViewToUIController(View, UIController)
, aby powiązać widok z niestandardowymUIController
.Aby dowiedzieć się, jak obsługiwać działanie z niestandardowego przycisku, zapoznaj się z artykułem Dodawanie działań niestandardowych (
MediaIntentReceiver
).
Oto przykład powiązania przycisku w miejscu 2 z elementem UIController
o nazwie 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); ... } }