Android TV 开发(4)
本文来自网易云社区
作者:孙有军
最后我们再来看看好友界面,改界面本地是没有xml的,因此我们直接来看看代码:
这里将使用到数据bean,与数据源的代码也贴出来如下:
public class Contact implements Parcelable {
private String phone;
private int headResId;
private String name;
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public int getHeadResId() {
return headResId;
}
public void setHeadResId(int headResId) {
this.headResId = headResId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Contact() {
}
public Contact(Parcel in) {
phone = in.readString();
headResId = in.readInt();
name = in.readString();
}
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(phone);
dest.writeInt(headResId);
dest.writeString(name);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(200);
sb.append("Contact{");
sb.append("phone='" + phone + '\'');
sb.append(", headResId='" + headResId + '\'');
sb.append(", name='" + name + '\'');
sb.append('}');
return sb.toString();
}
public static final Creator CREATOR = new Creator() {
public Contact createFromParcel(Parcel in) {
return new Contact(in);
}
public Contact[] newArray(int size) {
return new Contact[size];
}
};
}
//////
public class ContactProvider {
private static List<Contact> contactList;
private static Context sContext;
private static int[] head = {R.drawable.avater1, R.drawable.avater2, R.drawable.avater3, R.drawable.avater4, R
.drawable.avater5, R.drawable.avater6, R.drawable.avater7, R.drawable.avater8, R.drawable.avater9, R
.drawable.avater10, R.drawable.avater11, R.drawable.avater12};
private static String[] names = {"梦洁", "雅静", "韵寒", "莉姿", "沛玲", "欣妍", "歆瑶", "凌菲", "靖瑶", "瑾萱", "芳蕤", "若华"};
private static String[] phones = {"18618188630", "18158103936", "18620145337", "15116333186", "18618188630",
"18158103936", "18620145337", "15116333186", "18618188630", "18158103936", "18620145337", "18767106408"};
public static void setContext(Context context) {
if (sContext == null)
sContext = context;
}
public static List<Contact> getContactList() {
buildContact();
return contactList;
}
public static List<Contact> buildContact() {
if (null != contactList) {
return contactList;
}
contactList = new ArrayList<Contact>();
for (int i = 0; i < 12; ++i) {
contactList.add(buildContactInfo(phones[i], names[i], head[i]));
}
return contactList;
}
private static Contact buildContactInfo(String phone, String name, int resId) {
Contact contact = new Contact();
contact.setPhone(phone);
contact.setName(name);
contact.setHeadResId(resId);
return contact;
}
}
/*
* VerticalGridFragment shows a grid of videos
*/
public class VerticalGridFragment extends android.support.v17.leanback.app.VerticalGridFragment {
private static final String TAG = "VerticalGridFragment"; private static final int DEFAULT_COLUMNS = 4; private int numColumns = DEFAULT_COLUMNS; private ArrayObjectAdapter mAdapter; @Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate");
super.onCreate(savedInstanceState);
//setTitle(getString(R.string.vertical_grid_title));
getParams();
setupFragment();
} @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = super.onCreateView(inflater, container, savedInstanceState);
return root;
} private void setupFragment() {
VerticalGridPresenter gridPresenter = new VerticalGridPresenter(FocusHighlight.ZOOM_FACTOR_NONE);
gridPresenter.setNumberOfColumns(numColumns);
//gridPresenter.setShadowEnabled(false);
setGridPresenter(gridPresenter); mAdapter = new ArrayObjectAdapter(new ContactPresenter()); List<Contact> contacts = ContactProvider.getContactList();
mAdapter.addAll(0, contacts); setAdapter(mAdapter); setOnItemViewClickedListener(new ItemViewClickedListener());
setOnItemViewSelectedListener(new ItemViewSelectedListener());
} public void getParams() {
if (getArguments() != null) {
numColumns = getArguments().getInt(Extra.COLUMNS);
}
} private final class ItemViewClickedListener implements OnItemViewClickedListener {
@Override
public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder
rowViewHolder, Row row) { if (item instanceof Contact) {
Contact contact = (Contact) item;
// TODO
}
}
} private final class ItemViewSelectedListener implements OnItemViewSelectedListener {
@Override
public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder
rowViewHolder, Row row) {
}
} }
在Fragment中我们自己实现了一个ContactPresenter,该Presenter是仿照官方的CardPresenter,但是CardPresenter中使用的ImageCardView是系统support包中提供的控件,而ContactPresenter中使用的是自己自定义的控件, 代码如下:
public class ContactPresenter extends Presenter {
private static final String TAG = "CardPresenter";
private static int sSelectedBackgroundColor;
private static int sDefaultBackgroundColor;
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
Log.d(TAG, "onCreateViewHolder");
sDefaultBackgroundColor = parent.getResources().getColor(R.color.white_35_transparent);
sSelectedBackgroundColor = parent.getResources().getColor(R.color.white_60_transparent);
ContactView contactView = new ContactView(parent.getContext()) {
@Override
public void setSelected(boolean selected) {
updateCardBackgroundColor(this, selected);
super.setSelected(selected);
}
};
contactView.setFocusable(true);
contactView.setFocusableInTouchMode(true);
updateCardBackgroundColor(contactView, false);
return new ViewHolder(contactView);
}
private static void updateCardBackgroundColor(ContactView view, boolean selected) {
int color = selected ? sSelectedBackgroundColor : sDefaultBackgroundColor;
view.setBackgroundColor(color);
//view.findViewById(R.id.info_field).setBackgroundColor(color);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, Object item) {
Contact contact = (Contact) item;
ContactView contactView = (ContactView) viewHolder.view;
Log.d(TAG, "onBindViewHolder");
contactView.setHead(contact.getHeadResId());
contactView.setName(contact.getName());
contactView.setPhone(contact.getPhone());
}
@Override
public void onUnbindViewHolder(ViewHolder viewHolder) {
Log.d(TAG, "onUnbindViewHolder");
ContactView contactView = (ContactView) viewHolder.view;
// Remove references to images so that the garbage collector can free up memory
contactView.setHead(0);
}
}
ContactView是一个继承自LinearLayout的自定义控件,包含了一个ImageView和两个TextView。
到此整个界面的代码就完成了,接下来我们来看看遇到的问题。
问题列表
问题1:控件遥控器不能选中,不能导航
出现这种问题往往是控件没有设置android:focusable="true"属性,只有默认能够选中焦点的才不需要设置改属性,比如Button,EditText。
问题2:控件选中后,看不出选中效果
由于默认选中是没有视觉效果的,因此你需要对控件设置选中效果,比如说背景图片,以前在手机上可能只需要设置selector中的pressed属性,或者selected属性,现在针对TV你必须要设置focused属性,比如拨号键盘选中后会出现一个圆形的选中背景框,
要实现上述效果,因此对每一键盘输入按钮添加如下的selector。
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/key_board_hover" android:state_focused="true"></item>
<item android:drawable="@drawable/key_board_hover" android:state_pressed="true"></item>
<item android:drawable="@drawable/key_board_hover" android:state_checked="true"></item>
<item android:drawable="@color/transparent"></item> </selector> key_board_hover.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/white_35_transparent"></solid>
<size
android:width="40dp"
android:height="40dp"/>
</shape>
网易云免费体验馆,0成本体验20+款云产品!
更多网易研发、产品、运营经验分享请访问网易云社区
相关文章:
【推荐】 30分钟,让你彻底明白Promise原理
【推荐】 【网易严选】iOS持续集成打包(Jenkins+fastlane+nginx)
【推荐】 接口文档神器Swagger(上篇)
Android TV 开发(4)的更多相关文章
- 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 前言:近年来,智能 ...
随机推荐
- IOS微信6.7.4输入框失去焦点,软键盘关闭后,被撑起的页面无法回退到原来正常的位置
近期在开发微信H5页面时碰到这个问题,如图,软键盘弹起后,若原输入框被遮挡,页面整体将会上移,然而当输入框失焦,软键盘收起后,页面未恢复,这也是ios的微信版本更新6.7.4之后才遇到的bug. 目前 ...
- js为页面元素添加水印
近期有需求为页面部分区域添加上水印,通过在网上找到了js为页面添加水印的方法,后来经过自己的改进,可以实现为页面部分元素添加水印,最终效果如下图: 代码如下: function watermark(s ...
- jQuerychicun
jQuery 尺寸 方法 jQuery 提供多个处理尺寸的重要方法: width() height() innerWidth() innerHeight() outerWidth() outerHei ...
- CAD Import .NET支持AutoCAD DWG 2013
CADSoftTools发布了CAD Import .NET 9一个新版本.NET开发库,可以提供给开发人员导入AutoCAD DWG.DXF.HPGL.PLT.CGM等格式的功能. 在新版本中,CA ...
- c#中反射技术在Unity中的运用
反射技术给类赋值的好处就是可以简化代码,封装的好处就显而易见了.最直接的用途就是用在在显示配置文件的时候,个人习惯性做法是做一个VO来存储需要的数据,其代码如下: internal class Bas ...
- fpga 状态机 检测1011序列
1011 可以使用4个状态:s0,s1,s2,s3. 即:(1)s0有0或1两个状态,当s0位0时,进入s0状态,自身打圈.为1那么进入下个状态s1来检测0. (2)s1有0或1两种情况,s1为1时s ...
- linux 命令——31 /etc/group文件(转)
Linux /etc/group文件与/etc/passwd和/etc/shadow文件都是有关于系统管理员对用户和用户组管理时相关的文件. linux /etc/group文件是有关于系统管理员对用 ...
- IOS UIActivityIndicatorView动画
● 是一个旋转进度轮,可以用来告知用户有一个操作正在进行中,一般 用initWithActivityIndicatorStyle初始化 ● 方法解析: ● - (void)startAnimating ...
- 2018.10.29 NOIP2018模拟赛 解题报告
得分: \(70+60+0=130\)(\(T3\)来不及打了,结果爆\(0\)) \(T1\):简单的求和(点此看题面) 原题: [HDU4473]Exam 这道题其实就是上面那题的弱化版,只不过把 ...
- 倍增LCA
前言 在做树上问题时,我们经常会遇到 \(LCA\)(最近公共祖先)问题.曾经的我遇到这类问题只会\(O(n)\)暴力求解,学了倍增\(LCA\),就可以\(O(logn)\)解决了. 简介 倍增\( ...