Android TV 开发 (1)
本文来自网易云社区
作者:孙有军
前言
这里主要记录几个TV问题的解决方案,如果对这个不感兴趣的其实就不用往下看了。
这几天有一个需求就是要求出一个TV版本的app,之前没有具体的了解Tv版的app有手机端的app到底有什么区别,因此就做了一下研究,写了些Demo,在做的过程中确实出现了好几个问题。一开始碰到这些问题时,浅尝辄止的试了试,发现很多都没有解决方案,本着外事问google的,search了一把,也没有结果,可能是TV做的人比较少,网上搜出来的都是照着谷歌官方的样例实现了一把而已,因此就仔细的研究了一下这些问题,这里把解决这些问题的方案描述出来,希望其他人能少走弯路,如果有更好的解决方案也希望大家探讨分享。
开发过程
虽然google官方写的是手机app不用做太多改动就可以运行在Tv上,但是终究两种还是有部分区别的,这里还是要针对TV版做部分设置。
首先是配置文件的改动,需要在AndroidManifest中配置如下属性:
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false"/>
<uses-feature
android:name="android.software.leanback"
android:required="true"/>
同时还需要配置一个action为android.intent.action.MAIN,category为android.intent.category.LEANBACK_LAUNCHER的Activity,类似如下:
<activity
android:name="im.yixin.home.HomeActivity"
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>
如果记不住上面需要配置的内容其实也没有关系,可以新创建一个TV工程,默认创建的TV工程就已经包含了上述的配置,并且该工程就相当于一个demo了,是可以直接运行的一个工程,里面包含了Tv开发的很多控件,如果你要学习这也是很好的学习资料了,其实后续的内容也是根据这里的内容进行参照学习的。
这里附带一句,Android的sdk中的samples中的tv样例程序直接导入是运行不起来的,需要修改很多东西,但是实质内容与新创建的工程没有什么区别,因此也可以不用导入样例程序进行学习了。
根据前面的样例图,主界面配置页面如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/global_bg"
android:orientation="vertical"
android:paddingLeft="42dp"
android:paddingRight="42dp"> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/gap_86_dp"
android:clickable="true"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:drawableLeft="@drawable/tv_logo"
android:drawablePadding="@dimen/gap_8_dp"
android:gravity="center"
android:text="@string/itv_name"
android:textColor="@color/white"
android:textSize="@dimen/text_size_20"/> <TextView
android:id="@+id/settings_tab"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_marginRight="@dimen/gap_45_dp"
android:background="@drawable/navigation_tab_bar_selector"
android:focusable="true"
android:gravity="center"
android:text="@string/setting"
android:textColor="@color/navigation_text_selector"
android:textSize="@dimen/text_size_20"/> <TextView
android:id="@+id/contact_tab"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="@dimen/gap_45_dp"
android:layout_toLeftOf="@id/settings_tab"
android:background="@drawable/navigation_tab_bar_selector"
android:focusable="true"
android:gravity="center"
android:text="@string/contact"
android:textColor="@color/navigation_text_selector"
android:textSize="@dimen/text_size_20"/> <TextView
android:id="@+id/dial_tab"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginRight="@dimen/gap_65_dp"
android:layout_toLeftOf="@id/contact_tab"
android:background="@drawable/navigation_tab_bar_selector"
android:focusable="true"
android:gravity="center"
android:text="@string/dial"
android:textColor="@color/navigation_text_selector"
android:textSize="@dimen/text_size_20"/>
</RelativeLayout> <View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginBottom="@dimen/gap_50_dp"
android:background="@color/gray1"/> <FrameLayout
android:id="@+id/tab_container"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
</LinearLayout>
界面的代码如下:
public class HomeActivity extends Activity implements View.OnClickListener {
public static void start(Context context) {
Intent intent = new Intent(context, HomeActivity.class);
context.startActivity(intent);
}
private static final String[] TAGS = {"dial", "contact", "my"};
private FragmentManager manager;
private int showTabIndex = -1;
private TextView dialTab;
private TextView contactTab;
private TextView myTab;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
findViews();
setViewsListener();
init();
selectTab(0);
}
private void findViews() {
dialTab = (TextView) findViewById(R.id.dial_tab);
contactTab = (TextView) findViewById(R.id.contact_tab);
myTab = (TextView) findViewById(R.id.settings_tab);
}
private void setViewsListener() {
dialTab.setOnClickListener(this);
contactTab.setOnClickListener(this);
myTab.setOnClickListener(this);
}
private void init() {
manager = getFragmentManager();
}
private void selectTab(int index) {
if (index == showTabIndex) {
return;
}
dialTab.setSelected(index == 0);
contactTab.setSelected(index == 1);
myTab.setSelected(index == 2);
FragmentTransaction transaction = manager.beginTransaction();
hideFragment(showTabIndex, transaction);
showTabIndex = index;
showFragment(showTabIndex, transaction);
transaction.commit();
}
private void hideFragment(int tabIndex, FragmentTransaction transaction) {
Fragment fragment = getFragmentByIndex(tabIndex);
if (fragment != null) {
transaction.hide(fragment);
}
}
private Fragment getFragmentByIndex(int index) {
if (index >= 0 && index < TAGS.length) {
return manager.findFragmentByTag(TAGS[index]);
}
return null;
}
private void showFragment(int tabIndex, FragmentTransaction transaction) {
Fragment fragment = getFragmentByIndex(tabIndex);
if (fragment == null) {
switch (tabIndex) {
case 0:
fragment = new DialFragment();
break;
case 1:
/* fragment = new ContactFragment();*/
fragment = new VerticalGridFragment();
break;
case 2:
fragment = new MyFragment();
break;
}
transaction.add(R.id.tab_container, fragment, TAGS[tabIndex]);
//transaction.addToBackStack(TAGS[tabIndex]);
} else {
transaction.show(fragment);
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.dial_tab:
selectTab(0);
return;
case R.id.contact_tab:
selectTab(1);
return;
case R.id.settings_tab:
selectTab(2);
// VerticalGridActivity.start(this);
return;
}
}
}
该界面主要采用Fragment来实现三个界面,分别为拨号页面,好友,设置界面,其中拨号界面又包含两个子的Fragment,我们来继续看看拨号界面与好友界面,设置界面是一个充数的界面啥都没有做。
网易云免费体验馆,0成本体验20+款云产品!
更多网易研发、产品、运营经验分享请访问网易云社区
相关文章:
【推荐】 基于Docker的UI自动化初探
【推荐】 深入解析SQLServer高可用镜像实现原理
【推荐】 Android输入法弹出时覆盖输入框问题
Android TV 开发 (1)的更多相关文章
- 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开发总结(一)构建一个TV app前要知道的事儿
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52792562 前言:近年来,智能 ...
随机推荐
- 完整部署OpenStack-memcache配置
一.[root@openstack-server ~]# nova listERROR (CommandError): You must provide a username or user id v ...
- C#应用调试C++ dll的方法
最近碰到个C#应用闪退的问题,由于通讯部分调用了C++工程写的dll,下面介绍一种调试的方法. 右键 启动项目,分别配置常规和和调试即可,如下图. 常规中,输出目录设置为安装目录中dll对应的目录: ...
- Android Studio 配置模拟器AVD存放路径(默认在c盘,解决c盘空间不够问题)
Android Studio 安装之后,默认的会给我们创建一个 Nexus 的模拟器, 这个模拟器的镜像文件放在了 C:\Users\Administrator\.android 中 其中的avd文 ...
- C#使用 SharpAVI进行 屏幕录制
再 nuget 中 搜索 shapAvi 并添加引用 github 地址:https://github.com/baSSiLL/SharpAvi using SharpAvi; using Sharp ...
- [ShaderStaff] Sprite Outline外轮廓效果
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Unity5.3.8f1 Unity提供了2D Object Sprite对象,但是没有提供外轮廓Outline效果的支持 ...
- Python编程总结之常用三方模块
1.excel读写 利用python进行excel读写是经常遇到的事情,最常用的excel读写模块必属xlrd和xlwt,前者负责读,后者负责写,配合起来可实现读写. 举例1):使用xlrd读取exc ...
- Java占位符替换工具类
import java.util.HashMap; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFact ...
- OK6410之tftp下载内核,nfs…
原文地址:OK6410之tftp下载内核,nfs挂载文件系统全过程详解[转]作者:千山我独行 由于工作的平台也是嵌入式,差不多的平台,所以一直就没有把自己买过来的ok6410板子好好玩玩.以前一直都是 ...
- smack 监听不同packet机制
之前做即时通讯,扒了smack源码来参考.说下其中解包后进行通知的机制. Filter类:accept(Packet packet)函数,传入packet在此函数中进行对比判断,返回true 则通过此 ...
- C# XML 操作
1 xml文件格式 <?xml version="1.0" encoding="utf-8"?> <userInfo> <user ...