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

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

浏览和播放媒体文件通常是电视应用程序提供的用户体验的一部分。 从零开始构建这样的体验,同时确保其快速,流畅和有吸引力可能是相当具有挑战性的。 无论您的应用是否提供对小型或大型媒体目录的访问,允许用户快速浏览选项并获取他们想要的内容非常重要。

Android框架提供了用于使用v17 leanback支持库为这些类型的应用程序构建用户界面的类。 这个库提供了一个类框架,用于创建一个高效且熟悉的界面,以最少的代码浏览和播放媒体文件。 这些课程旨在进行扩展和定制,以便您可以创建独特的应用体验。

本课程向您展示如何使用Leanback电视支持库构建浏览和播放媒体内容的电视应用程序。

了解如何使用Leanback支持库为媒体目录构建浏览界面。

了解如何使用Leanback支持库为内容项目构建卡片视图。

了解如何使用Leanback支持库为媒体项目构建详细信息页面。

了解如何使用Leanback支持库为您的视频播放器构建传输控件。

了解如何使用MediaSession在主屏幕上显示正在使用的即时贴。

了解您的应用如何直接在主屏幕的表面上呈现预览视频。

了解如何使用Leanback支持库来指导用户完成一系列决策。

了解如何使用Leanback支持库向初次使用者展示如何充分利用您的应用程序。

了解如何在用户点击主页时继续播放。

运行在电视上的媒体应用程序需要允许用户浏览其内容产品,进行选择并开始播放内容。 这种类型的应用程序的内容浏览体验应该简单直观,并且在视觉上令人愉悦且引人入胜。

本课讨论如何使用v17 leanback支持库提供的类来实现用于从应用媒体目录中浏览音乐或视频的用户界面。

图1. Leanback示例应用程序浏览片段显示视频目录数据。

leanback库中的BrowseFragment类允许您使用最少的代码创建用于浏览媒体项目类别和行的主要布局。 以下示例显示如何创建包含BrowseFragment对象的布局:

应用程序的主要活动设置此视图,如以下示例所示:

public class MainActivity extends Activity {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);    }...

BrowseFragment方法使用视频数据和UI元素填充视图,并设置布局参数(如图标,标题以及是否启用类别标题)。

有关设置UI元素的更多信息,请参阅设置 UI元素。

有关隐藏标题的更多信息,请参阅隐藏或禁用标题。

实现BrowseFragment方法的应用程序的子类还为UI元素上的用户操作设置事件侦听器,并准备后台管理器,如以下示例所示:

public class MainFragment extends BrowseFragment implements        LoaderManager.LoaderCallbacks>> {...    @Override    public void onActivityCreated(Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);        loadVideoData();        prepareBackgroundManager();        setupUIElements();        setupEventListeners();    }...    private void prepareBackgroundManager() {        mBackgroundManager = BackgroundManager.getInstance(getActivity());        mBackgroundManager.attach(getActivity().getWindow());        mDefaultBackground = getResources()            .getDrawable(R.drawable.default_background);        mMetrics = new DisplayMetrics();        getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics);    }    private void setupUIElements() {        setBadgeDrawable(getActivity().getResources()            .getDrawable(R.drawable.videos_by_google_banner));        // Badge, when set, takes precedent over title        setTitle(getString(R.string.browse_title));        setHeadersState(HEADERS_ENABLED);        setHeadersTransitionOnBackEnabled(true);        // set headers background color        setBrandColor(getResources().getColor(R.color.fastlane_background));        // set search icon color        setSearchAffordanceColor(getResources().getColor(R.color.search_opaque));    }    private void loadVideoData() {        VideoProvider.setContext(getActivity());        mVideosUrl = getActivity().getResources().getString(R.string.catalog_url);        getLoaderManager().initLoader(0, null, this);    }    private void setupEventListeners() {        setOnSearchClickedListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                Intent intent = new Intent(getActivity(), SearchActivity.class);                startActivity(intent);            }        });        setOnItemViewClickedListener(new ItemViewClickedListener());        setOnItemViewSelectedListener(new ItemViewSelectedListener());    }...

在上面的示例中,私有方法setupUIElements()调用了几个BrowseFragment方法来设置媒体目录浏览器的样式:

setBadgeDrawable()将指定的可绘制资源放置在浏览片段的右上角,如图1和2所示。如果还调用了setTitle() ,则此方法将用可绘制资源替换标题字符串。 可绘制的资源应该是52dps高。

除非setBadgeDrawable() ,否则setBadgeDrawable()会在浏览片段的右上角设置标题字符串。

setBrandColor()使用指定的颜色值为浏览片段中的UI元素(特别是标题部分背景颜色setBrandColor()设置背景颜色。

setSearchAffordanceColor()用指定的颜色值设置搜索图标的颜色。 搜索图标出现在浏览片段的左上角,如图1和2所示。

图1中显示的浏览片段列出了左侧窗格中的视频类别名称(行标题)。 文本视图显示视频数据库中的这些类别名称。 您可以自定义标题以在更复杂的布局中包含其他视图。 以下部分显示如何包含图像视图,该图像视图在类别名称旁边显示图标,如图2所示。

图2.浏览片段中的行标题,带有图标和文本标签。

行标题的布局定义如下:

使用Presenter并实现抽象方法来创建,绑定和取消绑定视图持有者。 以下示例显示如何使用两个视图(一个ImageView和一个TextView来绑定视图。

public class IconHeaderItemPresenter extends Presenter {    @Override    public ViewHolder onCreateViewHolder(ViewGroup viewGroup) {        LayoutInflater inflater = (LayoutInflater) viewGroup.getContext()                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);        View view = inflater.inflate(R.layout.icon_header_item, null);        return new ViewHolder(view);    }    @Override    public void onBindViewHolder(ViewHolder viewHolder, Object o) {        HeaderItem headerItem = ((ListRow) o).getHeaderItem();        View rootView = viewHolder.view;        ImageView iconView = (ImageView) rootView.findViewById(R.id.header_icon);        Drawable icon = rootView.getResources().getDrawable(R.drawable.ic_action_video, null);        iconView.setImageDrawable(icon);        TextView label = (TextView) rootView.findViewById(R.id.header_label);        label.setText(headerItem.getName());    }    @Override    public void onUnbindViewHolder(ViewHolder viewHolder) {    // no op    }}

你的头文件必须是可以调焦的,这样D-pad可以用来滚动它们。 有两种选择:

@Overridepublic void onBindViewHolder(ViewHolder viewHolder, Object o) {    HeaderItem headerItem = ((ListRow) o).getHeaderItem();    View rootView = viewHolder.view;    rootView.setFocusable(true) // Allows the D-Pad to navigate to this header item    //...}

将您的布​​局设置为可对焦:

android:focusable="true">

setHeaderPresenterSelector(new PresenterSelector() {    @Override    public Presenter getPresenter(Object o) {        return new IconHeaderItemPresenter();    }});

有关完整示例,请参阅leanback示例中的IconHeaderItemPresenter。

例如,有时您可能不希望行标题出现:当没有足够的类别需要可滚动列表时。 在片段的onActivityCreated()方法中调用BrowseFragment.setHeadersState()方法来隐藏或禁用行标题。 setHeadersState()方法将以下常量之一作为参数,设置浏览片段中标题的初始状态:

HEADERS_ENABLED - 创建浏览片段活动时,默认情况下会启用并显示标题。 标题的显示如图1和2所示。

HEADERS_HIDDEN - 创建浏览片段活动时,标题默认情况下处于启用和隐藏状态。 屏幕的标题部分已折叠,如提供卡片视图的 图1所示。 用户可以选择折叠页眉部分来展开它。

HEADERS_DISABLED - 创建浏览片段活动时,标题默认处于禁用状态,并且不会显示。

BrowseFragment类允许您使用适配器和演示BrowseFragment从媒体目录中定义和显示可浏览的媒体内容类别和媒体项目。 适配器使您能够连接到包含媒体目录信息的本地或联机数据源。 适配器使用演示者创建视图并将数据绑定到这些视图以在屏幕上显示项目。

以下示例代码显示了用于显示字符串数据的Presenter的实现:

public class StringPresenter extends Presenter {    private static final String TAG = "StringPresenter";    public ViewHolder onCreateViewHolder(ViewGroup parent) {        TextView textView = new TextView(parent.getContext());        textView.setFocusable(true);        textView.setFocusableInTouchMode(true);        textView.setBackground(                parent.getContext().getResources().getDrawable(R.drawable.text_bg));        return new ViewHolder(textView);    }    public void onBindViewHolder(ViewHolder viewHolder, Object item) {        ((TextView) viewHolder.view).setText(item.toString());    }    public void onUnbindViewHolder(ViewHolder viewHolder) {        // no op    }}

一旦为媒体项目构建了演示者类,就可以构建一个适配器并将其附加到BrowseFragment以在屏幕上显示这些项目以供用户浏览。 以下示例代码演示了如何使用前面的代码示例中显示的StringPresenter类构造适配器以显示这些类别中的类别和项目:

private ArrayObjectAdapter mRowsAdapter;private static final int NUM_ROWS = 4;@Overrideprotected void onCreate(Bundle savedInstanceState) {    ...    buildRowsAdapter();}private void buildRowsAdapter() {    mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());    for (int i = 0; i < NUM_ROWS; ++i) {        ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(                new StringPresenter());        listRowAdapter.add("Media Item 1");        listRowAdapter.add("Media Item 2");        listRowAdapter.add("Media Item 3");        HeaderItem header = new HeaderItem(i, "Category " + i);        mRowsAdapter.add(new ListRow(header, listRowAdapter));    }    mBrowseFragment.setAdapter(mRowsAdapter);}

此示例显示适配器的静态实现。 典型的媒体浏览应用程序使用来自在线数据库或Web服务的数据。 有关使用从Web检索的数据的浏览应用程序的示例,请参阅Android Leanback示例应用程序 。

为了在电视上为媒体浏览应用增加视觉趣味,您可以在用户浏览内容时更新背景图片。 这项技术可以使您的应用更具电影感和愉悦感。

Leanback支持库提供了一个BackgroundManager类,用于更改电视应用程序活动的背景。 以下示例显示如何创建一个简单方法来更新电视应用程序活动中的背景:

protected void updateBackground(Drawable drawable) {    BackgroundManager.getInstance(this).setDrawable(drawable);}

当用户浏览媒体列表时,许多现有的媒体浏览应用会自动更新背景。 为了做到这一点,您可以设置一个选择侦听器,根据用户的当前选择自动更新背景。 以下示例显示如何设置OnItemViewSelectedListener类来捕获选择事件并更新背景:

protected void clearBackground() {    BackgroundManager.getInstance(this).setDrawable(mDefaultBackground);}protected OnItemViewSelectedListener getDefaultItemViewSelectedListener() {    return new OnItemViewSelectedListener() {        @Override        public void onItemSelected(Object item, Row row) {            if (item instanceof Movie ) {                Drawable background = ((Movie)item).getBackdropDrawable();                updateBackground(background);            } else {                clearBackground();            }        }    };}

注意:上面的实现是一个简单的例子,用于说明。 在自己的应用程序中创建此功能时,应考虑在单独的线程中运行后台更新操作以获得更好的性能。 此外,如果您计划更新背景以响应用户滚动浏览项目,请考虑增加一段时间来延迟背景图片更新,直到用户安置一个项目。 这种技术避免了过多的背景图像更新。

Android电视切换回放,Android Studio V3.12环境下TV开发教程(五)建立电视回放应用...相关推荐

  1. android studio3.12,Android Studio V3.12环境下TV开发教程(六)提供卡片视图

    Android Studio V3.12环境下TV开发教程 文章源自:光谷佳武 https://blog.csdn.net/jiawuhan/article/details/80619656 在上一课 ...

  2. Android Studio TV开发教程(五)建立电视回放应用

    Android Studio TV开发教程 (转自Android官网https://developer.android.com/training/tv/start) 文章源自:光谷佳武 https:/ ...

  3. Android Studio TV开发教程(二)管理电视控制器

    Android Studio TV开发教程 (转自Android官网https://developer.android.com/training/tv/start) 文章源自:光谷佳武 https:/ ...

  4. Android Studio TV开发教程(十六)让电视应用程序可搜索

    Android Studio TV开发教程 (转自Android官网https://developer.android.com/training/tv/start) 文章源自:光谷佳武 https:/ ...

  5. Android Studio TV开发教程(十二)帮助用户在电视上找到您的内容

    Android Studio TV开发教程 (转自Android官网https://developer.android.com/training/tv/start) 文章源自:光谷佳武 https:/ ...

  6. Android Studio TV开发教程(一)处理电视硬件

    Android Studio TV开发教程 (转自Android官网https://developer.android.com/training/tv/start) 文章源自:光谷佳武 https:/ ...

  7. Android Studio TV开发教程(十五) Android N及更早版本中的建议

    Android Studio TV开发教程 (转自Android官网https://developer.android.com/training/tv/start) 文章源自:光谷佳武 https:/ ...

  8. android中英文切换功能,Android APP 中英文切换

    实习期间,师父要求做app的中英文切换,就顺便记录了下. 一.AndroidManifest.xml文件(清单文件) 在每个要切换语言的Activity下面添加: android:configChan ...

  9. android tab 切换动画,Android之ViewPager+TabLayout组合实现导航条切换效果(微信和QQ底部多标签切换)...

    前言 之前在另外一篇中用Fragment和button实现了点击切换Fragment的效果,比较简陋.这次改用ViewPager+TabLayout 实现联动的效果. 实现效果 ViewPager 多 ...

最新文章

  1. 什么时候应该在内部联接上使用交叉应用?
  2. 【树莓派】树莓派SD卡系统镜像系统备份方法
  3. Python学习笔记:常用内建模块6 (urllib)
  4. extundelete安装_Linux数据安全工具:数据恢复软件extundelete概述
  5. C# WinFormDataGrideView 用内存数据源时的注意事项
  6. leetcode面试题 08.12. 八皇后(回溯)
  7. PyTorch 1.0 中文文档正式接受校对 | ApacheCN
  8. Angular 8 发布
  9. Python 运算符day04
  10. 在xp中运行 .air 文件--Adobe AIR Runtime for Window
  11. 关于adodb的简单介绍
  12. linux 怎么关闭输入法快捷键设置方法,关闭输入法快捷键
  13. 一窥Memory测试算法及自我修复机制
  14. centos7安装或升级Google chrome、安装Firefox浏览器详细过程及设置桌面快捷方式
  15. arduino教学:红外遥控车
  16. Word/Excel文档操作API哪家强?一张表带你了解Aspose和Spire系列全功能对比
  17. 有特别有创意的网站设计案例
  18. 马蜂窝用户内容贡献能力模型构建
  19. 塑料袋检测_塑料制品检测_注塑件视觉检测方案
  20. On Rate Distortion Optimization Using SSIM

热门文章

  1. LabVIEW+Proteus环境温湿度监控系统
  2. 【数字化】数字化工厂2020:塑造制造业的新未来
  3. background-size:contain 与cover的区别(转载)
  4. java税务软件_java税务管理系统
  5. java毕业设计LM美食推荐网Mybatis+系统+数据库+调试部署
  6. 【Unity3D-UGUI应用篇】(三)使用UGUI实现层级菜单
  7. [编译记录]遇到“ld: unsupported tapi file type ‘!tapi-tbd‘ in YAML file...”
  8. webuploader使用
  9. 01-夜神模拟器安装介绍
  10. 数据分析 | SQL基础查询语句+例题详解