安卓TV开发(四) 实现主流智能TV视频播放器UI

前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大量使用,但是这些设备上的开发并不是和传统手机开发一样,特别是焦点控制和用户操作TV上有很大的区别,本系列博文主要用TV播放器的实现去了解下在智能设备上的开发一个app的流程,实现遥控器控制焦点移动,方向键模拟鼠标,并在线完成视频直播,手机当遥控器使用等相关功能。

上一篇中 安卓TV开发(三) 实现主流TV视频播放器UI 初步学习了智能电视上UI的设计,且只实现了一个遥控器可控制的view父框架,但是里面的item还没有写完,至于怎么调用显示和运用我们今天就接着学习吧,

在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();

/**
	 * 获取数据.
	 */
	private void getData() {
		// 模拟网络获取数据
		mTvLists.add(new TvModle(R.drawable.jstv, "江苏卫视"));
		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, "北京爱情故事"));
	}

在上面的初始化方法中,我们会用到添加子控件的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上的视频播放器。

时间: 2024-10-05 11:27:52

安卓TV开发(四) 实现主流智能TV视频播放器UI的相关文章

安卓TV开发(十) 智能电视开发之在线视频直播

转载注明出处:http://blog.csdn.net/sk719887916/article/details/46582987 从<安卓TV开发(八) 移动智能终端多媒体之在线加载网页视频源> 中我总结了怎么去解析一个网页,获取里面数据实现展现,如何去播放视频呢,今天就给大家简单介绍下比较常用视频开源框架vitamio,  项目sdk地址:https://www.vitamio.org/en/  .              解压vitamio sdk 可以看到有个InitActivity的

Android TV开发总结(五)TV上屏幕适配总结

前言:前面几篇总结一些TV上的小Sample,开源到GitHub:https://github.com/hejunlin2013/TVSample, 点击链接,可以持续关注.今天总结下TV上屏幕适配.: 看下Agenda: 一.屏幕适配的一些背景知识 二.TV屏幕适配怎么适配?有哪些规则? 三.多屏幕适配,android读取res/drawable优先级是什么? 四.屏幕分辨率及density .densityDpi代码 一.屏幕适配的一些背景知识 介绍几个在Android屏幕适配上非常重要的名

iOS开发--XLVideoPlayer——基于AVFoundation自定义的视频播放器

本文聊点关于最近写的这个自定义播放器.支持UITableViewCell上小屏.全屏播放,手动及屏幕旋转切换,包括右下角的小窗悬停播放,不依赖于视图控制器和第三方,尽量的让使用起来更简单,具体代码详情请戳Github,先看看效果如何! 这是基于AVFoundation下自定义的一个播放器,先简单介绍几个用到的类. 介绍: AVPlayer:可以理解为播放器对象,灵活性好,可以高度化的自定义UI,但它本身不能显示视频,显示需要另一个类AVPlayerLayer来显示,继承于CALayer,下面是摘

橙子引擎携多款精品TV游戏诚意呈献 2014智能电视游戏品牌峰会

橙子引擎携多款精品TV游戏诚意呈献 2014智能电视游戏品牌峰会 活动时间:2014.12.26  14:00-17:00 活动地点:深圳南山科技园科兴科学园会议中心8号厅 主办单位:橙子引擎 协办单位:网势网络.浩动游戏 活动介绍: 智能电视游戏行业前景光明,但是也存在一些问题:游戏内容不够吸引人,大型游戏画面感粗糙,玩家无法更好的体验游戏带给他们的乐趣. 智能电视游戏行业亟需一款"现象级"游戏来引爆,那么它将会是下一款游戏么? 本次会议,橙子引擎联合众多明星游戏开发者,携<八

Android TV开发--实现延时关机功能(二)逻辑实现

模块功能描述(总述) 上一篇文章:Android TV开发--实现延时关机功能(一)功能描述 讲的是延时关机整体功能描述以及UI效果,这篇文章将着重讲解逻辑实现. 按照功能模块分为3部分:关机App.关机Service.Launcher 模块图如下: 关机App模块 主要功能:1.展示UI设置延时时长 2.取消延时关机 3.取消延时对话框倒计时功能 1.展示UI设置延时时长 此处即为延时关机功能入口: 1.布局及逻辑处理Activity如下,代码中含有注释: /** * 延时关机 */ publ

Android TV 开发相关文章

Android TV 开发相关文章 Android TV 开发与Android移动设备开发类似,网络上针对其开发文章较少,平时查阅关于TV 开发资料收集于此,方便日后查阅. 持续更新 --. Android TV 焦点特效实现浅析

Android TV开发总结(六)构建一个TV app的直播节目实例

请尊重分享成果,转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52966319 近年来,Android TV的迅速发展,传统的有线电视受到较大的冲击,在TV上用户同样也可以看到各个有线电视的直播频道,相对于手机,这种直播节目,体验效果更佳,尤其是一样赛事节目,大屏幕看得才够痛快,还可以邀几好友一起欣赏.今天将介绍构建一个TV app的直播节目实例,此实例上传到Github: https://github.com/hejunlin20

Android TV开发

前言 这里主要记录几个TV问题的解决方案,如果对这个不感兴趣的其实就不用往下看了. 这几天有一个需求就是要求出一个TV版本的app,之前没有具体的了解Tv版的app有手机端的app到底有什么区别,因此就做了一下研究,写了些Demo,在做的过程中确实出现了好几个问题.一开始碰到这些问题时,浅尝辄止的试了试,发现很多都没有解决方案,本着外事问google的,search了一把,也没有结果,可能是TV做的人比较少,网上搜出来的都是照着谷歌官方的样例实现了一把而已,因此就仔细的研究了一下这些问题,这里把

Android TV开发总结(一)构建一个TV app前要知道的事儿

转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52792562 前言:近年来,智能电视的发展如火如荼,Googel 也在大力推进TV及穿带设备的发展,在互联网的风口,是猪也会飞,这句话并不是没有道理的.传统电视机厂商,基本都转型致力于智能电视的相关业务. 处理电视硬件 app上检查电视设备 处理不支持的硬件features Declaring hardware requireme