Android TV 开发(5)
本文来自网易云社区
作者:孙有军
问题3:TV launcher中没有入口图标
如果需要出现入口图标,你必须要在AndroidManifest中配置action为android.intent.action.MAIN,category为android.intent.category.LAUNCHER的Activity。该配置与上面的LEANBACK_LAUNCHER不冲突,可以对入口Activity配置LAUNCHER,之后一个页面配置LEANBACK_LAUNCHER,配置如下:
<activity
android:name=".WelcomeActivity"
android:label="@string/app_name"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
</intent-filter></activity>
问题4:TV launcher中的图标不清晰,太糊
如果直接将手机app的launcher图标直接使用到TV中,则图标会拉伸,由于TV的图标往往都比较大,拉伸后就会变糊,因此需要重新切launcher图标,手机里面是4848, 7272,9696等,而tv需要更大的尺寸,虽然没有在官方找到建议的尺寸,但是这里推荐一个尺寸180180,可以多个文件夹都放同一个图标,这样界面加载的图标就会变得清晰。
问题5:遥控器导航下一个不是自己希望导航的控件
系统中如果界面中有多个可focus的控件,上下左右导航,则会找到与当前控件最邻近的控件作为下一个选中的控件,因此如果你确切想指定下一个导航的控件,则可以指定下一个控件的ID,只要该id在当前显示的界面中,比如向上 view1.setNextFocusUpId(R.id.dial_tab);
问题6:官方VerticalGridFragment加载后,默认选中第一个,但是第一个占据了整个界面。
该问题应该是官方的一个bug,如果不是第一次加载VerticalGridFragment,则不会出现该问题,并且我尝试了多个版本的,都会出现该问题,原因是选中后系统会在在选中的控件后插入两帧NonOverlappingView,插入的布局代码如下:
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v17.leanback.widget.NonOverlappingView
android:id="@+id/lb_shadow_normal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/lb_card_shadow_normal" />
<android.support.v17.leanback.widget.NonOverlappingView
android:id="@+id/lb_shadow_focused"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/lb_card_shadow_focused"
android:alpha="0" /> </merge>
该布局插入了两帧NonOverlappingView,每一帧都使用了一个.9图标作为背景,而当系统第一次加载时,最终第一个选中的控件宽高计算错误,计算成了一个16777211类似的一个值,远远超出了界面的大小,解决方案如下:
方案1,将布局中的match_parent改为wrap_content
方案2,对VerticalGridFragment中使用的VerticalGridPresenter设置ShadowEnabled,如gridPresenter.setShadowEnabled(false);
方案3,替换掉.9图片
问题7:VerticalGridFragment加载后,选中放大效果不居中
在VerticalGridFragment,如果ArrayObjectAdapter使用的是自己实现的Presenter,而Presenter使用的不是系统提供的ImageCardView,则会导致选中效果不居中,当选中效果放大后会向右向下覆盖,而不是在当前位置放大覆盖四周。
该问题,我查了对应的style、只有针对ImageCardView的style,我也还没有仔细研究怎么调整,不过这里给出一个避免的方案,对VerticalGridPresenter选中后的高亮效果选择为不放大,如new VerticalGridPresenter(FocusHighlight.ZOOM_FACTOR_NONE)。
问题8:VerticalGridFragment顶层控件不能向上导航
比如在联系人列表页第一行时,遥控器向上不能导航,比如不能导航到拨号,好友控件,该问题其实是被系统给拦截了。系统的VerticalGridFragment加载了lb_vertical_grid_fragment布局,该布局包含了一个BrowseFrameLayout,对
BrowseFrameLayout设置了setOnFocusSearchListener。如下:
private void setupFocusSearchListener() {
BrowseFrameLayout browseFrameLayout = (BrowseFrameLayout) getView().findViewById(
R.id.grid_frame);
browseFrameLayout.setOnFocusSearchListener(getTitleHelper().getOnFocusSearchListener());
}
当系统在VerticalGridPresenter最顶层时,向上找最近一个控件时,发现当前布局已经没有控件,则会向父布局查找,代码如下:
public View focusSearch(View focused, int direction) {
if (isRootNamespace()) {
// root namespace means we should consider ourselves the top of the
// tree for focus searching; otherwise we could be focus searching
// into other tabs. see LocalActivityManager and TabHost for more info
return FocusFinder.getInstance().findNextFocus(this, focused, direction);
} else if (mParent != null) {
return mParent.focusSearch(focused, direction);
} return null;
}
而VerticalGridPresenter的父布局则是BrowseFrameLayout,因此最终执行的是上面设置的getTitleHelper().getOnFocusSearchListener(),我们去看看改listener:
private final BrowseFrameLayout.OnFocusSearchListener mOnFocusSearchListener =
new BrowseFrameLayout.OnFocusSearchListener() {
@Override
public View onFocusSearch(View focused, int direction) {
if (focused != mTitleView && direction == View.FOCUS_UP) {
return mTitleView;
}
final boolean isRtl = ViewCompat.getLayoutDirection(focused) ==
View.LAYOUT_DIRECTION_RTL;
final int forward = isRtl ? View.FOCUS_LEFT : View.FOCUS_RIGHT;
if (mTitleView.hasFocus() && direction == View.FOCUS_DOWN || direction == forward) {
return mSceneRoot;
}
return null;
}
};
发现问题所在没有,当focused != mTitleView && direction == View.FOCUS_UP时,强制指定了mTitleView,就算没有没有显示title,效果也一样。我认为这应该算系统的一个bug,那怎么解决呐?
我们可以重写一个一模一样的lb_vertical_grid_fragment,自己写的布局会覆盖掉系统的布局,再将BrowseFrameLayout重写成我们自己的BrowseFrameLayout。如下
public class BrowseFrameLayout extends android.support.v17.leanback.widget.BrowseFrameLayout { public BrowseFrameLayout(Context context) { super(context);
} public BrowseFrameLayout(Context context, AttributeSet attrs) { super(context, attrs);
} public BrowseFrameLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle);
} /**
* Sets a {@link OnFocusSearchListener}.
*/
public void setOnFocusSearchListener(OnFocusSearchListener listener) {
}
}
问题9:VerticalGridFragment内容未占满整个屏幕
<!--BrowseFragment, RowsFragment, DetailsFragment padding 左边的距离</item>-->
<item name="browsePaddingStart">@dimen/lb_browse_padding_start</item>
<!--BrowseFragment, RowsFragment, DetailsFragment padding 右边的距离</item>-->
<item name="browsePaddingEnd">@dimen/lb_browse_padding_end</item>
<!--BrowseFragment padding 顶部的距离</item>-->
<item name="browsePaddingTop">@dimen/lb_browse_padding_top</item>
<!--BrowseFragment padding 底部的距离</item>-->
<item name="browsePaddingBottom">@dimen/lb_browse_padding_bottom</item>
<!--start margin of RowsFragment inside BrowseFragment when HeadersFragment is visible</item>-->
<item name="browseRowsMarginStart">@dimen/lb_browse_rows_margin_start</item>
<!--top margin of RowsFragment inside BrowseFragment when BrowseFragment title is visible</item>-->
<item name="browseRowsMarginTop">@dimen/lb_browse_rows_margin_top</item>
如果你使用的是BrowseFragment,则控制上述的边距,如果你使用的是VerticalGridFragment, 则复写itemsVerticalGridStyle,他也使用了上述定义的值,也可以直接设置具体的值:
<style name="ItemsVerticalGridStyle" parent="@style/Widget.Leanback.GridItems.VerticalGridView">
<item name="horizontalMargin">@dimen/gap_12_dp</item>
<item name="verticalMargin">@dimen/gap_12_dp</item> <item name="android:focusable">true</item>
<item name="android:focusableInTouchMode">true</item>
<item name="android:paddingStart">?attr/browsePaddingStart</item>
<item name="android:paddingEnd">?attr/browsePaddingEnd</item>
<item name="android:paddingBottom">@dimen/lb_vertical_grid_padding_bottom</item>
<item name="android:paddingTop">?attr/browseRowsMarginTop</item>
<item name="android:gravity">center_horizontal</item>
<item name="focusOutFront">true</item>
</style>
样式调整
如果你需要对VerticalGridFragment的某些样式进行调整,你可以重新定义一个Theme继承自Theme.Leanback,这里我们大致写其中几个效果。可以控制VerticalGridFragment的内容的四周的边距,也可以控制ImageCardView的视觉效果。
<style name="AppTheme" parent="@style/Theme.Leanback"> <!--BrowseFragment, RowsFragment, DetailsFragment padding 左边的距离</item>-->
<item name="browsePaddingStart">@dimen/lb_browse_padding_start</item>
<!--BrowseFragment, RowsFragment, DetailsFragment padding 右边的距离</item>-->
<item name="browsePaddingEnd">@dimen/lb_browse_padding_end</item>
<!--BrowseFragment padding 顶部的距离</item>-->
<item name="browsePaddingTop">@dimen/lb_browse_padding_top</item>
<!--BrowseFragment padding 底部的距离</item>-->
<item name="browsePaddingBottom">@dimen/lb_browse_padding_bottom</item>
<!--start margin of RowsFragment inside BrowseFragment when HeadersFragment is visible</item>-->
<item name="browseRowsMarginStart">@dimen/lb_browse_rows_margin_start</item>
<!--top margin of RowsFragment inside BrowseFragment when BrowseFragment title is visible</item>-->
<item name="browseRowsMarginTop">@dimen/lb_browse_rows_margin_top</item>
<!--fading edge length of start of browse row when HeadersFragment is visible</item>-->
<item name="browseRowsFadingEdgeLength">@dimen/lb_browse_rows_fading_edge</item> <item name="baseCardViewStyle">@style/BaseCardViewStyle</item> <item name="overlayDimMaskColor">@color/transparent</item>
<item name="overlayDimActiveLevel">@fraction/lb_view_active_level</item>
<!--控制每一个item 背景投影</item>-->
<item name="overlayDimDimmedLevel">0%</item> <item name="itemsVerticalGridStyle">@style/ItemsVerticalGridStyle</item>
</style> <style name="BaseCardViewStyle" parent="@style/Widget.Leanback.BaseCardViewStyle">
<item name="cardForeground">@color/transparent</item>
<item name="cardBackground">@color/transparent</item>
</style> <style name="ItemsVerticalGridStyle" parent="@style/Widget.Leanback.GridItems.VerticalGridView">
<item name="horizontalMargin">@dimen/gap_12_dp</item>
<item name="verticalMargin">@dimen/gap_12_dp</item> <item name="android:focusable">true</item>
<item name="android:focusableInTouchMode">true</item>
<item name="android:paddingStart">?attr/browsePaddingStart</item>
<item name="android:paddingEnd">?attr/browsePaddingEnd</item>
<item name="android:paddingBottom">@dimen/lb_vertical_grid_padding_bottom</item>
<item name="android:paddingTop">?attr/browseRowsMarginTop</item>
<item name="android:gravity">center_horizontal</item>
<item name="focusOutFront">true</item>
</style> <style name="ImageCardViewInfoAreaStyle" parent="@style/Widget.Leanback.ImageCardView.InfoAreaStyle">
<item name="android:background">@null</item>
</style> <style name="ImageCardViewStyle" parent="@style/Widget.Leanback.ImageCardViewStyle">
<item name="cardBackground">@color/transparent</item>
</style>
网易云免费体验馆,0成本体验20+款云产品!
更多网易研发、产品、运营经验分享请访问网易云社区
相关文章:
【推荐】 GitLab 自动触发 Jenkins 构建(2)
Android TV 开发(5)的更多相关文章
- Android TV开发总结(六)构建一个TV app的直播节目实例
请尊重分享成果,转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52966319 近年来,Android TV的迅速发展,传统的有线电视受 ...
- Android TV开发总结(五)TV上屏幕适配总结
前言:前面几篇总结一些TV上的小Sample,开源到GitHub:https://github.com/hejunlin2013/TVSample, 点击链接,可以持续关注.今天总结下TV上屏幕适配. ...
- Android TV开发总结(三)构建一个TV app的焦点控制及遇到的坑
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52835829 前言:上篇中,&l ...
- 聊聊真实的 Android TV 开发技术栈
智能电视越来越普及了,华为说四月发布智能电视跳票了,一加也说今后要布局智能电视,在智能电视方向,小米已经算是先驱了.但是还有不少开发把智能电视简单的理解成手机屏幕的放大,其实这两者并不一样. 一.序 ...
- Android TV开发总结(七)构建一个TV app中的剧集列表控件
原文:Android TV开发总结(七)构建一个TV app中的剧集列表控件 版权声明:我已委托"维权骑士"(rightknights.com)为我的文章进行维权行动.转载务必转载 ...
- Android TV开发中所有的遥控器按键监听及注意事项,新增home键监听
原文:Android TV开发中所有的遥控器按键监听及注意事项,新增home键监听 简单记录下android 盒子开发遥控器的监听 ,希望能帮到新入门的朋友们 不多说,直接贴代码 public cla ...
- Android TV开发总结(四)通过RecycleView构建一个TV app列表页(仿腾讯视频TV版)
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52854131 前言:昨晚看锤子手 ...
- Android TV开发总结(二)构建一个TV Metro界面(仿泰捷视频TV版)
前言:上篇是介绍构建TV app前要知道的一些事儿,开发Android TV和手机本质上没有太大的区别,屏大,焦点处理,按键处理,是有别于有手机和Pad的实质区别.今天来介绍TV中Metro UI风格 ...
- Android TV 开发 (1)
本文来自网易云社区 作者:孙有军 前言 这里主要记录几个TV问题的解决方案,如果对这个不感兴趣的其实就不用往下看了. 这几天有一个需求就是要求出一个TV版本的app,之前没有具体的了解Tv版的app有 ...
- Android TV开发总结(一)构建一个TV app前要知道的事儿
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52792562 前言:近年来,智能 ...
随机推荐
- Win 10 关闭了.net framework 3.5后再开启不成功
背景: Win10 想要使用IETester来测试下页面的浏览器兼容性.在“控制面板”里关闭了.net framework 3.5,再重新开启. 问题: 在重新开启的时候,提示不成功.错误代码0x80 ...
- apache反向代理设置
为了方便在内网测试微信接口API <VirtualHost *:80> ServerName wx.abc.com ProxyPreserveHost on ProxyPass / htt ...
- 用windows计划任务执行一些内容的写法,
用windows计划任务执行一些内容的写法, 以下示例: 1.创建ws对象 2.关闭java进程 3.执行bat文件 start.vbe文件内容 set ws=wscript.createobject ...
- JavaScript中hasOwnProperty函数
JavaScript中hasOwnProperty函数方法是返回一个布尔值,指出一个对象是否具有指定名称的属性. 使用方法: object.hasOwnProperty(proName) 其中参数 ...
- 【转】 vxWorks下常用的几种延时方法
在应用编程的时候,通常会碰到需要一个任务在特定的延时之后执行一个指定的动作,如等待外设以确保数据可靠,控制扬声器发声时间以及串口通信超时重发等.这就需要利用定时器机制来计量特定长度的时间段. vxWo ...
- CSS-背景-渐变-文本格式化
1.背景 1.背景色 属性:background-color 取值:合法的颜色值 注意:背景颜色和背景图片默认都从边框位置处开始填充 2.背景图片 属性:background-image 取值:url ...
- HQL和SQL查询
转自http://blog.csdn.net/aaa1117a8w5s6d/article/details/7757097 HQL和SQL的区别 标签: sqlhibernatejavasessio ...
- canvas 实现赛车小游戏
一:样式 <style> #btn{ width: 60px; height: 30px; line-height: 30px; background: #7EC0EE; border: ...
- ios 基础知识篇 堆和栈的区别
前言 堆和栈是什么?有什么区别?是干嘛的? 内存管理 移动设备的内存及其有限,每一个APP所能占用的内存是有限制的 (吐槽一下:iPhone6s还是16G起步,还好我也买不起->_-> 扯 ...
- 2019.01.26 codeforces 528D. Fuzzy Search(fft)
传送门 fftfftfft好题. 题意简述:给两个字符串s,ts,ts,t,问ttt在sss中出现了几次,字符串只由A,T,C,GA,T,C,GA,T,C,G构成. 两个字符匹配的定义: 当si−k, ...