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输入法弹出时覆盖输入框问题