接下去应该是梳理一下 Android Tv 主界面实现原理及解析的一个系列博客了,大体上的安排是先介绍 Google 官方提供的 Leanback 库的使用,如何使用该库来实现简单的 Home 界面,然后再去分析 Leanback 主界面实现的相关源码,了解完 Google 是如何实现之后就可以扔掉 Leanback 自己来尝试实现,毕竟 Leanback 的可定制不高。


效果图

首先贴几张常见的 Home 界面效果:

第一张是爱奇艺 Tv 应用的 Home 界面,第二张是一个开源 Demo 的 Home 界面,第三张是 Google 官方 Tv Sample 的 Home 界面

比较常见的 Home 界面风格应该是第一张和第二张的形式,这两种的 ui 实现也不一样,因此我就想搞懂这两种界面分别是如何实现的!!

目前重点研究第一张的实现方式吧,毕竟 Google 的 Leanback 库实现出来的效果跟第一张有一些共同点,因此可以从 Leanback 入手来学习它是如何实现的。而至于第二张的实现原理,目前还没有思路,也暂时找不到相关资料来学习,Github 上面的 demo 都是忽悠人,控件全都是在 xml 中直接写死的,所以第二张图的 Home 界面实现原理以后再慢慢研究吧,或者有读者可以指点一二,非常感激。

分析

先大概的来分析一下第一张爱奇艺 Home 界面的实现:

这个是 Tab 标签栏,选中不同的 Tab,内容区会显示不同的视频列表,这里的实现应该是 TabLayout + Fragment 的形式,或者 TabLayout + ViewPager,但 ViewPager 在 Tv 上使用好像会出很多坑。

这个是内容区域即可左右滑动又可上下滑动的视频列表区域,主页最复杂的实现应该就是这个地方了。要我实现的话,思路就是 RecyclerView 嵌套 RecyclerView 来实现,先不谈 RecyclerView 这种滑动的控件在 Tv 上会出问题,嵌套这个坑就足够你填的了。

在 Tv 上,可以用 HorizontalGridView 和 VerticalGridView 替代 RecyclerView 使用。但要实现左右单行滑动,上下整体滑动的效果,我只能想到上下用 VerticalGridView 来实现,每一行是它 itemView,而每一行的实现则用 HorizontalGridView 来实现。也就是 1 个 VerticalGridView + 多个 HorizontalGridView 来实现。

但这样的嵌套仍会有许多问题出现,比如快速移动时的焦点丢失、性能问题、每一行的 View 如何缓存、复用等。

有大佬清楚解决方案,或者有其他实现思路的小伙伴们欢迎指点一下,实在没有,那就只能自己慢慢去啃 Leanback 的相关源码,然后再来梳理一下了。

使用

不出意外,接下去的空闲时间应该就是啃 Leanback Home 界面实现的相关源码,在此之前,先了解一下 Leanback 如何使用,哪些类是重点,后面分析时才方便入手。

以下是我觉得应该理解的类:

  • BrowerFragment:用来展示可左右上下滑动的视频列表界面
  • ArrayObjectAdapter:作用类似于 List,可以用于装每一行的数据,也可以用于装一行里的每一个 item 数据
  • ListRowPresenter:Leanback 库中的 Presenter 作用都有些类似于 RecyclerView.Adapter
  • ListRow:可以理解成一个 Mode,也就是把每一行抽象封装成一个 ListRow

用法跟 RecyclerView 很像,就是可能单独从命名上来理解会有些乱。只要你自己尝试去利用 Leanback 去实现个最简单的 Home 界面,大体就能理解了。比如,要实现下面这个 Home 界面:

首先,界面显示的数据都存在 ArrayObjectAdapter 里面,在 RecyclerView 时我们是存在 ArrayList 里:

初始化 ArrayObjectAdapter 对象时需传入一个 Presenter 进去,这里跟 RecyclerView 的使用有些不同,在 RecyclerView 里,我们是将 List 对象传给 Adapter,让 Adapter 去将数据和 itemView 绑定。这里虽然反过来将 Adapter(Presenter) 传入 List(ArrayObjectAdapter) 里,但其实作用也差不多,也是将两者关联起来。只是多了一个步骤,通过一个桥梁类 ItemBridgeAdapter 来将 ArrayObjectAdapter 里的数据传给 Presenter 。之后 Presenter 的工作就跟 RecyclerView.Adapter 一样了。

前面说了 Presenter 作用类似于 Adapter,它是个抽象类,继承它的之类需要实现三个方法:onCreateViewHolder()、onBindViewHolder()、onUnbindViewHolder(),同 RecyclerView.Adapter 一样,在 onCreateViewHolder() 里面创建 itemView,然后在 onBindViewHolder() 里面将数据和 itemView 绑定,比如:

最后调用 BrowerFragment 的 setAdapter() 将总的 ArrayObjectAdapter 对象设置进去,就可以了。使用很简单,如果你第一次接触,然后直接来看这篇,也许看不懂,建议你去看看这篇博客,或者自己去看一下 Google 官方的 Tv demo,然后再回来看,相信你理解就会跟深刻了。

思考

  1. 学会初步使用 Leanback 实现一个简单的 Home 界面后,你会发现,我们只需要提供每一行的数据,以及每行自己 itemView 的布局和数据绑定方式即可。但这完全没有涉及到 HorizontalGridView 和 VerticalGridView ,那么它内部的实现原理又是什么呢?

  2. 如果你运行了 Google 官方 Tv sample 或者自己利用 Leanback 实现了简单的 Home 界面的话,你会发现,我们焦点在某个 item 上时,这个 item 会放大,焦点离开又恢复正常,这个 Leacback 又是怎么实现的呢?

  3. 如果你运行了爱奇艺的 Tv 应用,你会发现,它焦点在移动到边界时 item 会有抖动的效果,这又要如何实现呢?

本系列梳理博客大概就是要理清上面的问题,后两个比较简单,看了 Leanback 的源码,已基本明白。所以难啃的点还是在于 Home 界面的 ui 实现原理,目前只能大体上明白每一行是一个 HorizontalGridView,上下滑动是由什么实现还没啃透。下一篇等啃得差不多了,再来梳理一下。

AndroidTv Home界面实现原理(一)——Leanback 库的使用的更多相关文章

  1. AndroidTv Home界面实现原理(二)——Leanback 库的主页卡位缩放动画源码解析

    先看个效果图: 上一篇中,我们留了问题,在 Tv Home 界面这种很常见聚焦卡位放大动画效果,我们这一篇就来看看 Leanback 库是怎么实现的. 如果要我们自己实现的话,思路应该不难,就是写个放 ...

  2. 使用AsyncTask异步更新UI界面及原理分析

    概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...

  3. CodeFirst写界面——自己写客户端UI库

    何谓CBS程序 CBS程序就是Client+Browser+Service的程序 纯CS程序写界面,有各种难处,那么我就在Client端引入Browser,让Browser渲染基于HTML的UI界面 ...

  4. QT新建空白项目-添加QT设计师界面类时出现的各种库无法导入识别

    按照教材上先新建一个空的项目--添加Qt设计师界面类时 出现各种 库无法识别 解决方法: 在 .pro文件中加入一行 QT += widgets 去构建中先执行 qmake 然后再构建一下  ok了 ...

  5. xtrabackup原理,整库,单表,部分备份恢复

    物理备份xtrabackup原理 Percona XtraBackup(简称PXB)是 Percona 公司开发的一个用于 MySQL 数据库物理热备的备份工具,支持 MySQl(Oracle).Pe ...

  6. 55.Qt-将界面程序封装成静态库

    1.生成dll 然后选择创建静态链接库: 创建的时候,记得勾选QtGui,并且修改pro文件,添加下面1句(这样就可以创建界面了): 修改staticlib.cpp: #include "s ...

  7. 54.Qt-将界面程序封装成动态库DLL

    1.生成dll 然后选择创建共享库: 创建好后,修改pro文件,改为下面两句(这样就可以创建界面了):  然后修改sharedlib.h: #ifndef SHAREDLIB_H #define SH ...

  8. 【情人节选帽子】TCS34725颜色传感器和Python图形界面编程(STM32 HAL库)

    截图 描述: l  STM32 HAL库编程 l  使用模拟IIC通信,方便程序移植 l  Python界面编写,蘑菇头的帽子是什么颜色 l  STM32 HAL库串口通信 l  Python界面使用 ...

  9. ThinkPHP内置标签库原理(Cx标签库)

    任何一个模板引擎的功能都不可能是为你量身定制的,具有一个良好的可扩展 机制也是模板引擎的另外一个考量,Smarty采用的是插件方法来实现扩展,ThinkTemplate由于采用了标签库技术,比Smar ...

随机推荐

  1. Echarts折线图表断点如何补全

    Echarts折线图如何补全断点以及如何隐藏断点的title 做报表的时候,尤其是做图表的时候时常会碰到某一记录的值中缺少某个时间段(比如月份或季度)的值,导致图表显示残缺不全,for example ...

  2. Android - FragmentTabHost 与 Fragment 制作页面切换效果

    使用 FragmentTabHost 与 Fragment 制作页面切换效果 API 19 TabHost已经不建议使用了.用 FragmentTabHost 来代替TabHost.实际上 Fragm ...

  3. ZigZag - 曲折字符串

    需求:将所给的字符串以“倒N型”输出,可以指定输出的行数函数 String convert(String s, int numRows)例如输入“abcdefghijklnmopqrstuvwxyz” ...

  4. PHP闭包和高阶函数

    <?php function func($a, $b) { $line = function ($x) use ($a, $b) { return $a*$x + $b; }; return $ ...

  5. java webservice简单的例子

    开发环境:eclipse .jdk 创建服务端 demo-webservice 创建类 HelloService.java package com.hundsun.ws.service; import ...

  6. Linux编译安装程序(使用configure、make、 make install)

    以安装vim为例. (vim 是vi的升级版本,它不仅兼容vi的所有指令,而且还有一些新的特性在里面). 1.获取源文件 首先进入/usr/local下(只是为了方便处理安装文件,位置随意) 用git ...

  7. phpMyAdmin安装部署

    phpMyAdmin 是一个用PHP编写的软件工具,可以通过web方式控制和操作MySQL数据库.通过phpMyAdmin 可以完全对数据库进行操作,例如建立.复制和删除数据等等.如果使用合适的工具, ...

  8. [学习笔记] Splay Tree 从入门到放弃

    前几天由于出行计划没有更博QwQ (其实是因为调试死活调不出来了TAT我好菜啊) 伸展树 伸展树(英语:Splay Tree)是一种二叉查找树,它能在O(log n)内完成插入.查找和删除操作.它是由 ...

  9. [技术] OIer的STL入门教程

    注: 本文主要摘取STL在OI中的常用技巧应用, 所以可能会重点说明容器部分和算法部分, 且不会讨论所有支持的函数/操作并主要讨论 C++11 前支持的特性. 如果需要详细完整的介绍请自行查阅标准文档 ...

  10. 写移动端必备的meta标签

    <meta name="renderer" content="webkit" /> <meta http-equiv="X-UA-C ...