يمكنك تخصيص تطبيقات 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/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) عندما تتغيّر حالة جلسة البث أو جلسة الوسائط. يجب أن تأخذ الفئة الفرعية منUIControllerImageViewكإحدى المَعلمات وتعدّل حالتها حسب الحاجة.يمكنك إنشاء فئة فرعية من
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 لتجاوز الأزرار التي تظهر في الخانات. يتم تحديد قائمة أزرار التحكّم المتوافقة كموارد تعريف مطابقة لأنواع أزرار وحدة التحكّم المصغّرة.
في ما يلي مثال يضع زر الإرجاع في الخانة الثانية، وزر التخطي للأمام في الخانة الثالثة، ويترك الخانتين الأولى والأخيرة فارغتين:
// 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); ... } }