Android Studio V3.12环境下TV开发教程(八)使用Leanback运输控制

Android Studio V3.12环境下TV开发教程

(转自Android官网https://developer.android.com/training/tv/start)

文章源自:光谷佳武 https://blog.csdn.net/jiawuhan/article/details/80620433

使用Leanback运输控制

Leanback库具有新的播放控件,可提供改进的用户体验。 对于视频应用程序,传输控件使用向前/向后控件支持视频清理。 清理显示屏时会显示缩略图,以帮助浏览视频。

该库包含抽象类以及为开发人员提供更精细控制的开箱即用实现。 使用预构建的实现,您可以快速构建功能丰富的应用程序,而无需太多编码。 如果您需要更多定制,您可以扩展任何库的预构建组件。

控件和播放器

leanback库将用户界面与回放视频的播放器中的传输控件分开。 这是通过两个组件完成的:一个用于显示传输控件(可选视频)的播放片段和一个用于封装媒体播放器的播放器适配器 。

播放片段

您应用的UI活动应使用PlaybackFragmentVideoFragment 。 两者都包含leanback运输控制:

PlaybackFragment根据需要动画其传输控件以隐藏/显示它们。

VideoFragment扩展了PlaybackFragment并具有SurfaceView来渲染视频。

您可以自定义片段的ObjectAdapter来增强UI。 例如,使用setAdapter()添加“相关视频”行。

PlayerAdapter

PlayerAdapter是一个控制底层媒体播放器的抽象类。 开发人员可以选择预先构建的MediaPlayerAdapter实现,或者编写他们自己的这个类的实现。

胶合在一起的碎片

您必须使用一些“控制胶水”将播放片段连接到播放器。 leanback库提供两种胶水:

PlaybackBannerControlGlue以“旧样式”绘制播放片段中的传输控件,将它们放置在不透明的背景中。 ( PlaybackBannerControlGlue取代了已弃用的PlaybackControlGlue 。)

PlaybackTransportControlGlue使用具有透明背景的“新样式”控件。

如果您希望您的应用支持视频清理,则必须使用PlaybackTransportControlGlue 。

您还需要指定一个将胶水绑定到回放片段的“胶水主机”,在UI中绘制传输控件并保持它们的状态,并将传输控制事件传递回胶水。 主机必须匹配回放片段类型。 将PlaybackFragmentGlueHostPlaybackFragmentGlueHost一起使用,并将VideoFragmentGlueHostVideoFragmentGlueHost一起使用。

下面是一个插图,展示了Leanback运输控制系统的各个部分如何配合在一起:

将您的应用粘合在一起的代码应该位于定义UI的PlaybackFragment或VideoFragment中。

在以下示例中,该应用程序构造PlaybackTransportControlGlue的实例,将其命名为playerGlue ,并将其VideoFragment连接到新创建的MediaPlayerAdapter 。 由于这是一个VideoFragment ,安装程序代码调用setHost()将VideoFragmentGlueHost附加到playerGlue 。 该代码包含在扩展VideoFragment的类中。

public class MyVideoFragment extends VideoFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final PlaybackTransportControlGlue playerGlue = new PlaybackTransportControlGlue(getActivity(), new MediaPlayerAdapter(getActivity())); playerGlue.setHost(new VideoFragmentGlueHost(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来处理来自媒体播放器的事件。

自定义UI胶水

您可以自定义PlaybackBannerControlGlue和PlaybackTrabsportControlGlue 。 改变PlaybackControlsRow 。

自定义标题和说明

要自定义播放控件顶部的标题和说明,请覆盖onCreateRowPresenter() :

@Override protected PlaybackRowPresenter onCreateRowPresenter() { PlaybackTransportRowPresenter presenter = (PlaybackTransportRowPresenter) super.onCreateRowPresenter(); presenter.setDescriptionPresenter(new MyCustomDescriptionPresenter()); return presenter; }

添加控件

控件胶水会显示PlaybackControlsRow操作的控件。

PlaybackControlsRow中的操作分配给两组: 主要操作辅助操作 。 主要组的控件出现在搜索栏上方,而次要组的控件出现在搜索栏下方。 最初,播放/暂停按钮只有一个主要操作,并且没有次要操作。

您可以通过覆盖onCreatePrimaryActions()onCreateSecondaryActions()来添加主要和次要组的操作。

private PlaybackControlsRow.RepeatAction mRepeatAction; private PlaybackControlsRow.PictureInPictureAction mPipAction; private PlaybackControlsRow.ThumbsUpAction mThumbsUpAction; private PlaybackControlsRow.ThumbsDownAction mThumbsDownAction; private PlaybackControlsRow.SkipPreviousAction mSkipPreviousAction; private PlaybackControlsRow.SkipNextAction mSkipNextAction; private PlaybackControlsRow.FastForwardAction mFastForwardAction; private PlaybackControlsRow.RewindAction mRewindAction; @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(mSkipPreviousAction); primaryActionsAdapter.add(mRewindAction); primaryActionsAdapter.add(mFastForwardAction); primaryActionsAdapter.add(mSkipNextAction); } @Override protected void onCreateSecondaryActions(ArrayObjectAdapter adapter) { super.onCreateSecondaryActions(adapter); adapter.add(mThumbsDownAction); adapter.add(mThumbsUpAction); }

您必须重写onActionClicked()来处理新的操作。

@Override public void onActionClicked(Action action) { if (action == mRewindAction) { // Handle Rewind } else if (action == mFastForwardAction ) { // Handle FastForward } else if (action == mThumbsDownAction) { // Handle ThumbsDown } else if (action == mThumbsUpAction) { // 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响应查找操作。

视频擦洗

如果您的应用使用VideoFragment并且您想支持视频清理。

您需要提供PlaybackSeekDataProvider的实现。 此组件提供滚动时使用的视频缩略图。 您必须通过扩展PlaybackSeekDataProvider来实现自己的提供者。 请参阅leanback-showcase应用程序中的示例。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容