安卓TV开发(四) 实现主流智能TV视频播放器UI
前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大量使用,但是这些设备上的开发并不是和传统手机开发一样,特别是焦点控制和用户操作体验上有很大的区别,本系列博文主要用TV播放器的实现去了解下在智能设备上的开发一个app的流程,实现遥控器控制焦点移动,方向键模拟鼠标,并在线完成视频直播,手机当遥控器使用等相关功能。其实此UI也适用于车载设备。
上一篇中 安卓TV开发(三) 实现主流TV视频播放器UI 初步学习了智能电视上UI的设计,且只实现了一个遥控器可控制的view父框架,但是里面的item还没有写完,至于怎么调用显示和运用我们今天就接着学习吧,
本文出处:http://blog.csdn.net/sk719887916
在FocusView中需要添加一个FocusItemModle 用于填充父布局,这个FocusItemModle 类似grideView中itemview一样,我们可以这么理解,现在我们就定义一个FocusItemModle 类,代码如下:
public class FocusItemModle {
private View mFocusView = null;
/**
* 起点行数
*/
private int mRow = 0;
/**
* view占据行数
*/
private int mRowSpan = 1;
/**
* 起点列数
*/
private int mCol = 0;
/**
* View占据列数
*/
private int mColSpan = 1;
/**
* @param v
* @param row
* @param col
*/
public FocusItemModle(View v, int row, int col) {
this(v, row, 1, col, 1);
}
/**
* @param v
* @param row
* @param rowspan
* @param col
* @param colspan
*/
public FocusItemModle(View v, int row, int rowspan, int col, int colspan) {
mFocusView = v;
setPosition(row, col);
if (rowspan < 1)
throw new IllegalArgumentException("rowspan < 1");
mRowSpan = rowspan;
if (colspan < 1)
throw new IllegalArgumentException("colspan < 1");
mColSpan = colspan;
}
public View getMetroView() {
return mFocusView;
}
public int getRow() {
return mRow;
}
public int getRowSpan() {
return mRowSpan;
}
public int getCol() {
return mCol;
}
public int getColSpan() {
return mColSpan;
}
public void setPosition(int row, int col) {
if (row < 0)
throw new IllegalArgumentException("row < 0");
mRow = row;
if (col < 0)
throw new IllegalArgumentException("col < 0");
mCol = col;
}
此item主要控制focusView显示在第几排第几列,用于返回一个itemView显示在focusView中。
再写好这些主要view之前,便于以后项目的扩展我们就专门写一个javaBean---,TvModle,也为了迎合mvc设计模式,用来将服务器数据映射到view上。
public class TvModle {
/**
* 图片资源
*/
private int image;
/**
* 标题
*/
private String name;
/**
* url
*/
private String url;
/**
* 简介或信息
*/
private String info;
/**
* 日期
*/
private String date;
/**
* 包括子节目
*/
private List childs;
public TvModle() {
super();
}
public TvModle(int image, String name) {
super();
this.image = image;
this.name = name;
}
public int getImage() {
return image;
}
public void setImage(int image) {
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public List getChilds() {
return childs;
}
public void setChilds(List childs) {
this.childs = childs;
}
}
等写好了view和中间层,接下来我们就开始写要显示该UI的activty,这里我们主要是New一个focusView,通过不断往里面加入一个个不同的itemView。
activty:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mian_tv_ui);
FocusView view = (FocusView) findViewById(R.id.focus_ui);
view.setBackgroundColor(Color.WHITE);
view.setGap(5);
view.setVisibleItems(6, 5);
view.setOrientation(OrientationType.Horizontal);
view.setAnimation(R.anim.scale_small, R.anim.scale_big);
/*view.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(FocusView metroView, View view, int col, int row,
long id) {
Toast.makeText(getApplicationContext(),col+"", 1).show();
}
});*/
getData();
// 添加自定义VIEW
view.addFocusItem(
getTvView(mTvLists.get(0).getName(),mTvLists.get(0).getImage(),0, 3, 0, 2));
view.addFocusItem(
getTvView(mTvLists.get(1).getName(),mTvLists.get(1).getImage(),3, 3, 0, 2));
view.addFocusItem(
getTvView(mTvLists.get(2).getName(),mTvLists.get(2).getImage(),0, 2, 2, 1));
view.addFocusItem(
getTvView(mTvLists.get(3).getName(),mTvLists.get(3).getImage(),0, 2, 3, 1));
view.addFocusItem(
getTvView(mTvLists.get(4).getName(),mTvLists.get(4).getImage(),0, 2, 4 ,1));
view.addFocusItem(
getTvView(mTvLists.get(5).getName(),mTvLists.get(5).getImage(),2, 2, 2, 1));
view.addFocusItem(
getTvView(mTvLists.get(6).getName(),mTvLists.get(6).getImage(),2, 2, 3, 1));
view.addFocusItem(
getTvView(mTvLists.get(7).getName(),mTvLists.get(7).getImage(),2, 2, 4 ,1));
view.addFocusItem(
getTvView(mTvLists.get(8).getName(),mTvLists.get(8).getImage(),4, 2, 2, 1));
view.addFocusItem(
getTvView(mTvLists.get(9).getName(),mTvLists.get(9).getImage(),4, 2, 3, 1));
view.addFocusItem(
getTvView(mTvLists.get(10).getName(),mTvLists.get(10).getImage(),4, 2, 4 ,1));
//添加默认logo
view.addFocusItem(getDefView(0, 2, 5, 1));
view.addFocusItem(getDefView(0, 2, 6, 1));
view.addFocusItem(getDefView(0, 2, 7 ,1));
view.addFocusItem(getDefView(0, 2, 8 ,1));
view.addFocusItem(getDefView(0, 2, 9 ,1));
view.addFocusItem(getDefView(2, 2, 5, 1));
view.addFocusItem(getDefView(2, 2, 6, 1));
view.addFocusItem(getDefView(2, 2, 7 ,1));
view.addFocusItem(getDefView(2, 2, 8 ,1));
view.addFocusItem(getDefView(2, 2, 9 ,1));
}
这里的代码比较好理解,只是将我们所要的控件找到,加入多个子item,getdata()是用来模拟获取服务数据的,本次demo暂时写到activity中,企业开发中建议单独写个manager用来控制网络层获取数据,下面是getDate(); 本文出处:http://blog.csdn.net/sk719887916
// 模拟网络获取数据 mTvLists.add(new TvModle(R.drawable.atm, "阿童木重磅来袭")); mTvLists.add(new TvModle(R.drawable.sdyjq, "速度与激情大片在线看")); mTvLists.add(new TvModle(R.drawable.yyt, "音悦台")); mTvLists.add(new TvModle(R.drawable.cntv, "中国网络电视台")); mTvLists.add(new TvModle(R.drawable.shtv, "东方卫视")); mTvLists.add(new TvModle(R.drawable.hutv, "芒果卫视")); mTvLists.add(new TvModle(R.drawable.gstv, "甘肃卫视")); mTvLists.add(new TvModle(R.drawable.cntv, "江苏卫视")); mTvLists.add(new TvModle(R.drawable.shtv, "东方卫视")); mTvLists.add(new TvModle(R.drawable.pptv, "pptv")); mTvLists.add(new TvModle(R.drawable.aqy, "爱奇艺")); mTvLists.add(new TvModle(R.drawable.cntv, "中国网络电视台")); mTvLists.add(new TvModle(R.drawable.atm, "阿童木重磅来袭")); mTvLists.add(new TvModle(R.drawable.sdyjq, "速度与激情大片在线看")); mTvLists.add(new TvModle(R.drawable.bjaqgs, "北京爱情故事")); mTvLists.add(new TvModle(R.drawable.hutv, "芒果卫视")); mTvLists.add(new TvModle(R.drawable.gstv, "甘肃卫视")); mTvLists.add(new TvModle(R.drawable.cntv, "江苏卫视")); mTvLists.add(new TvModle(R.drawable.shtv, "东方卫视"));
在上面的初始化方法中,我们会用到添加子控件的view的方法,通过getTview()和getDefView(),前面方法用于指定显示我们所要的itemView,后面方法是显示默认的view
/**
* getTvView
* @param title
* @param rouseid
* @param row
* @param rowspan
* @param col
* @param colspan
* @return FocusItemVew
*/
private FocusItemModle getTvView(String title, int rouseid, int row, int rowspan,
int col, int colspan) {
LinearLayout layout = getLinearLayout();
layout.setGravity(Gravity.CENTER);
FrameLayout frameLayout = new FrameLayout(this);
frameLayout.setPadding(PADDING, PADDING, PADDING, PADDING);
TextView mTextView = new TextView(this);
mTextView .setText(title);
mTextView .setGravity(Gravity.CENTER);
mTextView .setTextColor(Color.BLACK);
mTextView .setTextSize(15);
ImageView mLogoView = new ImageView(this);
mLogoView.setLayoutParams(FILL_FILL);
mLogoView.setImageResource(rouseid);
frameLayout.addView(mLogoView, FILL_FILL);
frameLayout.addView(mTextView , WRP_WRP);
layout.addView(frameLayout);
return new FocusItemModle(layout, row, rowspan, col, colspan);
}
private FocusItemModle getDefView(int row, int rowspan, int col, int colspan) {
LinearLayout layout = getLinearLayout();
TextView tv2 = new TextView(this);
tv2.setText("频道"+(i ++));
tv2.setGravity(Gravity.CENTER);
tv2.setTextColor(Color.WHITE);
tv2.setTextSize(15);
layout.addView(tv2, FILL_FILL);
return new FocusItemModle(layout, row, rowspan, col, colspan);
}
再次我们还需要用到填充activty的Layout的xmL,比较简单
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.example.tv_ui_demo.tvView.FocusView
android:id="@+id/focus_ui"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
通过上篇文章结合本次文章,我们初步实现了一个在安卓TV上显示,并且可以用遥控器控制上下左右移动的效果UI,但由于只是demo,并非实际项目,所以效果比较粗糙,但是并不影响代码质量,以上的代码在tv上没有任何bug,但是运行在手机上是存有缺陷的,如果需要兼容手机,TV和手机公用一个版本的话,代码需要优化,但我本人不建议手机和电视版本公用一个版本,这样对UI的适配和焦点控制会带来众多麻烦,手机也无需这么大的使徒,但是不仿喜欢的朋友自己去完善和扩展,况且电视的操作体验是比较简单的,并且无法触屏的(但也有触屏的电视,价格不菲)后面我会继续完善本次demo,结合第三方开源视频框架,完成一个简易的tv上的视频播放器。本文出处:http://blog.csdn.net/sk719887916
方向键控制效果如下:
源码:https://github.com/Tamicer/FocusView
更多技术文章请关注本人微信公众号:
安卓TV开发(四) 实现主流智能TV视频播放器UI的更多相关文章
- 安卓TV开发(概述) 智能电视之视觉设计和体验分析
转载说明出处 :http://blog.csdn.net/sk719887916, 作者:skay 前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大 ...
- 安卓TV开发(十) 智能电视开发之在线视频直播
转载注明出处:http://blog.csdn.net/sk719887916/article/details/46582987 从<安卓TV开发(八) 移动智能终端多媒体之在线加载网页视频源& ...
- Android TV开发总结(五)TV上屏幕适配总结
前言:前面几篇总结一些TV上的小Sample,开源到GitHub:https://github.com/hejunlin2013/TVSample, 点击链接,可以持续关注.今天总结下TV上屏幕适配. ...
- 安卓TV开发(五) 移动智能终端UI之实现主流TV焦点可控UI
载请标明出处:http://blog.csdn.net/sk719887916,作者:skay 由于其他网站收录,导致你无法查看本系列原创文章请点击此处 安卓TV开发(四)实现主流智能T ...
- 安卓TV开发(三) 移动智能设备之实现主流TV电视盒子焦点可控UI
前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大量使用,但是这些设备上的开发并不是和传统手机开发一样,特别是焦点控制和用户操作体验上有很大的区别,本系列博文主 ...
- 安卓TV开发(六) 移动智能终端UI之实现类似GridView的焦点控制FocusView框架
转载请标明出处:http://blog.csdn.net/sk719887916/article/details/40045089,作者:skay 前言 安卓TV开发(五) 移动智能终端UI之实现主流 ...
- Android TV开发总结(三)构建一个TV app的焦点控制及遇到的坑
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52835829 前言:上篇中,&l ...
- 你是否有一个梦想?用JavaScript[vue.js、react.js......]开发一款自定义配置视频播放器
前言沉寂了一周了,打算把这几天的结果呈现给大家.这几天抽空就一直在搞一个自定义视频播放器,为什么会有如此想法?是因为之前看一些学习视频网站时,看到它们做的视频播放器非常Nice!于是,就打算抽空开发一 ...
- 安卓Tv开发(一)移动智能电视之焦点控制(触控事件)
前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大量使用,但是这些设备上的开发并不是和传统手机开发一样,特别是焦点控制和用户操作体验风格上有很大的区别,本系列博 ...
随机推荐
- MongoDB 查询文档
语法 MongoDB 查询数据的语法格式如下: >db.COLLECTION_NAME.find() find() 方法以非结构化的方式来显示所有文档. 如果你需要以易读的方式来读取数据,可以使 ...
- Java中的Lock锁
Lock锁介绍: 在java中可以使用 synchronized 来实现多线程下对象的同步访问,为了获得更加灵活使用场景.高效的性能,java还提供了Lock接口及其实现类ReentrantLock和 ...
- Java对象锁和类锁全面解析(多线程synchronized关键字)
最近工作有用到一些多线程的东西,之前吧,有用到synchronized同步块,不过是别人怎么用就跟着用,并没有搞清楚锁的概念.最近也是遇到一些问题,不搞清楚锁的概念,很容易碰壁,甚至有些时候自己连用没 ...
- CentOS环境下使用GIT基于Nginx的私服搭建全过程
阅读本文前你必须预先装好CentOS并且已经安装和配置好Nginx了. 安装GIT私服套件 安装centos6.5-centos7.0 安装nginx yum install -y?git gitwe ...
- jboss规则引擎KIE Drools 6.3.0 Final 教程(1)
前言 目前世面上中文的KIE DROOLS Workbench(JBOSS BRMS)的教程几乎没有,有的也只有灵灵碎碎的使用机器来翻译的(翻的不知所云)或者是基于老版本的JBOSS Guvnor即5 ...
- 六星经典CSAPP-笔记(11)网络编程
六星经典CSAPP-笔记(11)网络编程 参照<深入理解计算机系统>简单学习了下Unix/Linux的网络编程基础知识,进一步深入学习Linux网络编程和TCP/IP协议还得参考Steve ...
- Eclipse调试(1)——基础篇
作为使用Eclipse的程序员都会使用它的Debug.但是有不少人只会用F6.F8,其他功能知之甚少.今天我就来总结一下我在使用eclipse的debug时的一些个人经验.水平有限,不足之处还请赐教. ...
- 在Windows cmd中计算行数
本文主体来自这篇外文文章的翻译.原文中有一个副标题:"如何简单地用Windows自带的FIND在CMD.exe中计算行数" 当我们在命令行环境中工作时,能计算其它工具输出内容的行数 ...
- Android程序员必须掌握的知识点-多进程和多线程
当某个应用组件启动且该应用没有运行其他任何组件时,Android 系统会使用单个执行线程为应用启动新的 Linux 进程.默认情况下,同一应用的所有组件在相同的进程和线程(称为"主" ...
- ROS机器人程序设计(原书第2版)补充资料 教学大纲
ROS机器人程序设计(原书第2版) 补充资料 教学大纲 针对该书稍后会补充教学大纲.教案.多媒体课件以及练习题等. <ROS机器人程序设计>课程简介 课程编号:XXXXXX 课程名称:RO ...