第一次开发Android TV经验总结
转自:http://ranseti.top/article/android_tv_1
Android TV开发不同于手机开发,第一、电视通过遥控器控制,而手机可以直接触摸屏幕,所以电视焦点控制比较麻烦。第二、TV开发适配主要做机顶盒适配,不同的机顶盒会输出不同的分辨率,而手机需要适配的的是不同的屏幕。
一、焦点控制,关于焦点自己最后总结为,给可以获取焦点的View在xml中设置:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:focusable="false"
android:layout_gravity="center_horizontal"
android:orientation="vertical"
tools:context="cn.v1.kanglewanjia.ui.LoginActivity">
<ImageView
android:layout_width="@dimen/dp_73"
android:layout_height="@dimen/dp_73"
android:layout_marginTop="@dimen/dp_128"
android:layout_gravity="center_horizontal"
android:focusable="false"
android:src="@drawable/icon_login" />
<LinearLayout
android:layout_width="@dimen/dp_452"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_34"
android:focusable="false"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:focusable="false"
android:text="手机号"
android:textColor="@color/white"
android:textSize="@dimen/sp_18" />
<EditText
android:id="@+id/et_phone_number"
android:layout_width="@dimen/dp_382"
android:layout_height="@dimen/dp_52"
android:layout_marginLeft="@dimen/dp_16"
android:background="@drawable/selector_login_et"
android:focusable="true"
android:hint="请输入中国大陆11位手机号码"
android:inputType="number"
android:maxLength="11"
android:paddingLeft="@dimen/dp_30"
android:textColor="@color/white"
android:textSize="@dimen/sp_18"
android:text="13810205545" />
</LinearLayout>
<LinearLayout
android:layout_width="@dimen/dp_452"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_14"
android:focusable="false"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:focusable="false"
android:text="验证码"
android:textColor="@color/white"
android:textSize="@dimen/sp_18" />
<EditText
android:id="@+id/et_verification_code"
android:layout_width="0dp"
android:layout_height="@dimen/dp_52"
android:layout_marginLeft="@dimen/dp_16"
android:layout_weight="1"
android:background="@drawable/selector_login_et"
android:focusable="true"
android:hint="请输入6位验证码"
android:inputType="number"
android:maxLength="6"
android:paddingLeft="@dimen/dp_30"
android:textColor="@color/white"
android:textSize="@dimen/sp_18"
tools:text="" />
<TextView
android:id="@+id/tv_send"
android:layout_width="@dimen/dp_113"
android:layout_height="@dimen/dp_52"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/dp_16"
android:background="@drawable/selector_login_button"
android:focusable="true"
android:gravity="center"
android:text="发送短信"
android:textColor="@color/white"
android:textSize="@dimen/sp_20" />
</LinearLayout>
<TextView
android:id="@+id/tv_login"
android:layout_width="@dimen/dp_382"
android:layout_height="@dimen/dp_52"
android:layout_marginTop="@dimen/dp_82"
android:layout_gravity="right"
android:background="@drawable/selector_login_button"
android:focusable="true"
android:gravity="center"
android:text="登录"
android:textColor="@color/white"
android:textSize="@dimen/sp_22" />
</LinearLayout>
上边是我项目中的登录页面,需要获取焦点并操作的View,给他一个选择器的background(主要为了看到焦点到什么地方了),然后设置
android:focusable="true"
background代码如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="@drawable/login_button_blue_bg"/>
<item android:drawable="@drawable/login_button_white_bg"/>
</selector>
焦点控制基本注意这些就可以了,然后在代码中完全和手机写法一模一样。如果需要做出View得焦点后出现放大的效果,可以参照gitHub项目: https://github.com/heyl1989/TvWidget
二、机顶盒适配,刚开始做的时候,UI给的图是1920X1080,我是按照手机像素除以2换算为dp,做出来后整个比例都比较小,只在电视中间一小块,特别别扭。随后看了很多博文,试着用像素除以1.5,并且把图片放到drawable-hdpi下。这次很完美,大小比例和效果图基本一样。因为开发的时候用的是联通的机顶盒,输出像素是1080X720。公司只有一台联通机顶盒,小米机顶盒却很多。为了测试,于是在小米机顶盒装了一个包,结果很伤心,丑的不能再丑。看到这篇博文后http://blog.csdn.net/u010212173/article/details/79075517 才知道,原来小米输出像素不同于联通机顶盒,所以在电视上显示的乱七八糟,于是只好建立values-w960dp,values-w1280dp用dimens做适配,values-w1280dp放联通适配的dp值,values-w960dp下的dimens值用values-w1280dp中dp值除以1.33。适配首页和登录页后效果很理想。在这里分享一个dimens文件自动生成的工具类:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
/**
* Created by qy on 2018/1/15.
* 快速生成适配工具类
*/
public class DimenTool {
public static void gen() {
//以此文件夹下的dimens.xml文件内容为初始值参照
File file = new File("./app/src/main/res/values-w1280dp/dimen.xml");
BufferedReader reader = null;
StringBuilder w960 = new StringBuilder();
try {
System.out.println("生成不同分辨率:");
reader = new BufferedReader(new FileReader(file));
String tempString;
int line = 1;
// 一次读入一行,直到读入null为文件结束
while ((tempString = reader.readLine()) != null) {
if (tempString.contains("</dimen>")) {
String start = tempString.substring(0, tempString.indexOf(">") + 1);
String end = tempString.substring(tempString.lastIndexOf("<") - 2);
//截取<dimen></dimen>标签内的内容,从>右括号开始,到左括号减2,取得配置的数字
Double num = Double.parseDouble
(tempString.substring(tempString.indexOf(">") + 1,
tempString.indexOf("</dimen>") - 2));
//根据不同的尺寸,计算新的值,拼接新的字符串,并且结尾处换行。
w960.append(start).append(num / 1.33).append(end).append("\r\n");
} else {
w960.append(tempString).append("");
}
line++;
}
reader.close();
System.out.println("<!-- w960 -->");
System.out.println(w960);
String w960file = "./app/src/main/res/values-w960dp/dimen.xml";
//将新的内容,写入到指定的文件中去
writeFile(w960file, w960.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
/**
* 写入方法
*/
public static void writeFile(String file, String text) {
PrintWriter out = null;
try {
out = new PrintWriter(new BufferedWriter(new FileWriter(file)));
out.println(text);
} catch (IOException e) {
e.printStackTrace();
}
out.close();
}
public static void main(String[] args) {
gen();
}
}
配置好参数后,直接点击运行main方法即可自动生成。第一次写博客,希望我写的话能够读通顺。