تتضمّن حزمة أدوات واجهة مستخدِم Leanback عناصر تحكّم في التشغيل توفّر تجربة استخدام محسّنة. في تطبيقات الفيديو، تتيح عناصر التحكّم في النقل تمرير الفيديو سريعًا باستخدام عناصر التحكّم في التقديم والترجيع. تظهر عند مسح الشاشة والصور المصغّرة للمساعدة في التنقل بين أقسام الفيديو.
تتضمّن المكتبة فئات مجردة بالإضافة إلى عمليات تنفيذ مُعدّة مسبقًا ومُعدّة للاستخدام مباشرةً، وتوفر للمطوّرين إمكانية التحكّم بشكل أدق. استخدام واجهة برمجة تطبيقات معدة مسبقًا عمليات التنفيذ، يمكنك إنشاء تطبيق غني بالميزات بسرعة وبدون الحاجة إلى ترميز كثيرًا. إذا كنت بحاجة إلى مزيد من التخصيص، يمكنك توسيع نطاق أيٍّ من المكوّنات المُعدّة مسبقًا في المكتبة.
عناصر التحكّم والمشغّل
تفصل مجموعة أدوات واجهة مستخدم Leanback واجهة المستخدم لعناصر التحكم في النقل المشغّل الذي يشغّل الفيديو. ويتم تحقيق ذلك من خلال عنصرين: جزء دعم التشغيل لعرض عناصر التحكم في النقل (و فيديو اختياريًا) ومحوّل مشغّل لتغليف مشغّل وسائط.
جزء من الفيديو
يجب أن يستخدم نشاط واجهة المستخدم في تطبيقك ملفًا شخصيًا على Google باستخدام PlaybackSupportFragment
أو VideoSupportFragment
.
يحتوي كلاهما على عناصر التحكّم في تشغيل الفيديوهات في وضع الاسترخاء:
- يعرض
PlaybackSupportFragment
عناصر التحكّم في النقل بشكل متحرك لإخفائها أو عرضها حسب الحاجة. - يمتد نطاق
VideoSupportFragment
للسمةPlaybackSupportFragment
ويتضمّن العنصرSurfaceView
لعرض الفيديو.
يمكنك تخصيص طريقة
ObjectAdapter
لتحسين واجهة المستخدم. على سبيل المثال، استخدِم
setAdapter()
لإضافة صف "الفيديوهات ذات الصلة".
مهايئ المشغّل
PlayerAdapter
هي فئة مجردة تتحكم في مشغّل الوسائط الأساسي. يمكن للمطوّرين الاختيار
تنفيذ MediaPlayerAdapter
المنشأة مسبقًا أو كتابة
كيفية تنفيذها لهذه الفئة.
لصق القطع معًا
يجب استخدام بعض "الغراء" لربط الجزء المخصص للتشغيل للّاعب. The leanback المكتبة نوعين من الغراء هما:
PlaybackBannerControlGlue
يرسم عناصر التحكّم في التشغيل في جزء التشغيل "بالطراز القديم"، ويضع هذه العناصر داخل خلفية غير شفافة. (PlaybackBannerControlGlue
يحلّ محلّPlaybackControlGlue
الذي تم إيقافه نهائيًا).PlaybackTransportControlGlue
يستخدم عناصر تحكّم "بالنمط الجديد" مع خلفية شفافة.
إذا كنت تريد أن يتيح تطبيقك تمرير الفيديو سريعًا أو بطيئًا، يجب استخدام
PlaybackTransportControlGlue
.
عليك أيضًا تحديد "مضيف ربط" يربط العنصر الرابط بجزء التشغيل، ويرسم عناصر التحكّم في التشغيل في واجهة المستخدم ويحافظ على حالتها، ويمرّر أحداث عناصر التحكّم في التشغيل مرة أخرى إلى العنصر الرابط. يجب أن يطابق المضيف نوع جزء التشغيل. استخدام
PlaybackSupportFragmentGlueHost
باستخدام
PlaybackFragment
و
VideoSupportFragmentGlueHost
مع
VideoFragment
في ما يلي رسم توضيحي يعرض كيفية تركيب أجزاء عنصر التحكّم في التشغيل/الإيقاف في وضع الاسترخاء:
يجب أن يكون الرمز البرمجي الذي يربط تطبيقك معًا داخل العلامة
PlaybackSupportFragment
أو VideoSupportFragment
التي تحدِّد واجهة المستخدم.
في المثال التالي،
ينشئ التطبيق مثيلًا منPlaybackTransportControlGlue
، ويسميهplayerGlue
، ويربطVideoSupportFragment
بمثيلMediaPlayerAdapter
تم إنشاؤه حديثًا. منذ
هذا VideoSupportFragment
يستدعي رمز الإعداد setHost()
لإرفاق
VideoSupportFragmentGlueHost
إلى playerGlue
يتم تضمين الرمز البرمجي داخل الصف
الذي يمتد إلى VideoSupportFragment
.
Kotlin
class MyVideoFragment : VideoSupportFragment() { fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) val playerGlue = PlaybackTransportControlGlue(getActivity(), MediaPlayerAdapter(getActivity())) playerGlue.setHost(VideoSupportFragmentGlueHost(this)) playerGlue.addPlayerCallback(object : PlaybackGlue.PlayerCallback() { override fun onPreparedStateChanged(glue: PlaybackGlue) { if (glue.isPrepared()) { playerGlue.seekProvider = MySeekProvider() playerGlue.play() } } }) playerGlue.setSubtitle("Leanback artist") playerGlue.setTitle("Leanback team at work") val uriPath = "android.resource://com.example.android.leanback/raw/video" playerGlue.getPlayerAdapter().setDataSource(Uri.parse(uriPath)) } }
Java
public class MyVideoFragment extends VideoSupportFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final PlaybackTransportControlGlue<MediaPlayerAdapter> playerGlue = new PlaybackTransportControlGlue(getActivity(), new MediaPlayerAdapter(getActivity())); playerGlue.setHost(new VideoSupportFragmentGlueHost(this)); playerGlue.addPlayerCallback(new PlaybackGlue.PlayerCallback() { @Override public void onPreparedStateChanged(PlaybackGlue glue) { if (glue.isPrepared()) { playerGlue.setSeekProvider(new MySeekProvider()); playerGlue.play(); } } }); playerGlue.setSubtitle("Leanback artist"); playerGlue.setTitle("Leanback team at work"); String uriPath = "android.resource://com.example.android.leanback/raw/video"; playerGlue.getPlayerAdapter().setDataSource(Uri.parse(uriPath)); } }
يُرجى العلم أنّ رمز الإعداد يحدِّد أيضًا PlayerAdapter.Callback
للتعامل مع الأحداث من
مشغّل الوسائط.
تخصيص الغراء لواجهة المستخدم
يمكنك تخصيص
PlaybackBannerControlGlue
وPlaybackTransportControlGlue
لتغيير
PlaybackControlsRow
تخصيص العنوان والوصف
لتخصيص العنوان والوصف في أعلى
عناصر التحكّم في التشغيل، إلغاء
onCreateRowPresenter()
:
Kotlin
override fun onCreateRowPresenter(): PlaybackRowPresenter { return super.onCreateRowPresenter().apply { (this as? PlaybackTransportRowPresenter) ?.setDescriptionPresenter(MyCustomDescriptionPresenter()) } }
Java
@Override protected PlaybackRowPresenter onCreateRowPresenter() { PlaybackTransportRowPresenter presenter = (PlaybackTransportRowPresenter) super.onCreateRowPresenter(); presenter.setDescriptionPresenter(new MyCustomDescriptionPresenter()); return presenter; }
جارٍ إضافة عناصر التحكّم
يعرض غراء التحكّم عناصر تحكّم في الإجراءات في "PlaybackControlsRow
".
يتمّ تعيين الإجراءات في PlaybackControlsRow
إلى مجموعتَين: الإجراءات الأساسية والإجراءات
الثانوية. تظهر عناصر التحكّم في المجموعة الأساسية أعلى شريط التمرير، وعناصر التحكّم في
المجموعة الثانوية أسفل شريط التمرير. في البداية، لا يتوفّر سوى إجراء أساسي واحد
لزر التشغيل/الإيقاف المؤقت، ولا تتوفّر إجراءات ثانوية.
يمكنك إضافة إجراءات إلى المجموعات الأساسية والثانوية من خلال إلغاء
onCreatePrimaryActions()
و
onCreateSecondaryActions()
Kotlin
private lateinit var repeatAction: PlaybackControlsRow.RepeatAction private lateinit var pipAction: PlaybackControlsRow.PictureInPictureAction private lateinit var thumbsUpAction: PlaybackControlsRow.ThumbsUpAction private lateinit var thumbsDownAction: PlaybackControlsRow.ThumbsDownAction private lateinit var skipPreviousAction: PlaybackControlsRow.SkipPreviousAction private lateinit var skipNextAction: PlaybackControlsRow.SkipNextAction private lateinit var fastForwardAction: PlaybackControlsRow.FastForwardAction private lateinit var rewindAction: PlaybackControlsRow.RewindAction override fun onCreatePrimaryActions(primaryActionsAdapter: ArrayObjectAdapter) { // Order matters, super.onCreatePrimaryActions() will create the play / pause action. // Will display as follows: // play/pause, previous, rewind, fast forward, next // > /|| |< << >> >| super.onCreatePrimaryActions(primaryActionsAdapter) primaryActionsAdapter.apply { add(skipPreviousAction) add(rewindAction) add(fastForwardAction) add(skipNextAction) } } override fun onCreateSecondaryActions(adapter: ArrayObjectAdapter?) { super.onCreateSecondaryActions(adapter) adapter?.apply { add(thumbsDownAction) add(thumbsUpAction) } }
Java
private PlaybackControlsRow.RepeatAction repeatAction; private PlaybackControlsRow.PictureInPictureAction pipAction; private PlaybackControlsRow.ThumbsUpAction thumbsUpAction; private PlaybackControlsRow.ThumbsDownAction thumbsDownAction; private PlaybackControlsRow.SkipPreviousAction skipPreviousAction; private PlaybackControlsRow.SkipNextAction skipNextAction; private PlaybackControlsRow.FastForwardAction fastForwardAction; private PlaybackControlsRow.RewindAction rewindAction; @Override protected void onCreatePrimaryActions(ArrayObjectAdapter primaryActionsAdapter) { // Order matters, super.onCreatePrimaryActions() will create the play / pause action. // Will display as follows: // play/pause, previous, rewind, fast forward, next // > /|| |< << >> >| super.onCreatePrimaryActions(primaryActionsAdapter); primaryActionsAdapter.add(skipPreviousAction); primaryActionsAdapter.add(rewindAction); primaryActionsAdapter.add(fastForwardAction); primaryActionsAdapter.add(skipNextAction); } @Override protected void onCreateSecondaryActions(ArrayObjectAdapter adapter) { super.onCreateSecondaryActions(adapter); adapter.add(thumbsDownAction); adapter.add(thumbsUpAction); }
عليك إلغاء
onActionClicked()
للتعامل مع الإجراءات الجديدة.
Kotlin
override fun onActionClicked(action: Action) { when(action) { rewindAction -> { // Handle Rewind } fastForwardAction -> { // Handle FastForward } thumbsDownAction -> { // Handle ThumbsDown } thumbsUpAction -> { // Handle ThumbsUp } else -> // The superclass handles play/pause and delegates next/previous actions to abstract methods, // so those two methods should be overridden rather than handling the actions here. super.onActionClicked(action) } } override fun next() { // Skip to next item in playlist. } override fun previous() { // Skip to previous item in playlist. }
Java
@Override public void onActionClicked(Action action) { if (action == rewindAction) { // Handle Rewind } else if (action == fastForwardAction ) { // Handle FastForward } else if (action == thumbsDownAction) { // Handle ThumbsDown } else if (action == thumbsUpAction) { // Handle ThumbsUp } else { // The superclass handles play/pause and delegates next/previous actions to abstract methods, // so those two methods should be overridden rather than handling the actions here. super.onActionClicked(action); } } @Override public void next() { // Skip to next item in playlist. } @Override public void previous() { // Skip to previous item in playlist. }
في حالات خاصة، قد تحتاج إلى تنفيذ
PlaybackTransportRowPresenter
لعرض عناصر تحكّم مخصّصة والردّ على إجراءات التقديم أو الإيقاف باستخدام
PlaybackSeekUi
.
تمرير الفيديو سريعًا أو ببطء
إذا كان تطبيقك يستخدم VideoSupportFragment
وتريد أن تتيح تنظيف الفيديو.
عليك
تقديم عملية تنفيذ PlaybackSeekDataProvider
.
يقدّم هذا المكوّن الصور المصغّرة للفيديوهات المستخدَمة عند الانتقال للأعلى أو للأسفل.
ويجب الاستعانة بمقدّم الخدمة الذي تتعامل معه من خلال تمديد
PlaybackSeekDataProvider
اطّلع على المثال في
تطبيق Leanback Showcase
.