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