يمكنك تخصيص أدوات 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 عند تغيير حالة جلسة البث أو جلسة الوسائط. يجب أن يتضمّن الصف الفرعي منUIController
ImageView
كأحد المَعلمات، وأن يعدّل حالته حسب الحاجة.أنشئ فئة فرعية
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 عند تغيير حالة جلسة البث أو جلسة الوسائط. يجب أن يتضمّن الصف الفرعي من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); ... } }