يمكنك تخصيص أدوات 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لذلك الزر المخصّص. بعد ذلك، استخدِم الأمر callbindViewToUIController(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 عند تغيُّر حالة جلسة البث أو جلسة الوسائط. يجب أن يتضمّن الصف الفرعي منUIControllerImageViewكأحد المَعلمات، وأن يتم تعديل حالته حسب الحاجة.استبدِل الفئة الفرعية ExpandedControllerActivity، ثم استبدِل
onCreateواستدعِgetButtonImageViewAt(int)للحصول على عنصر العرض الخاص بالزر. بعد ذلك، استخدِم الدالة callbindViewToUIController(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); ... } }