安卓Tv开发(一)移动智能电视之焦点控制(触控事件)
前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大量使用,但是这些设备上的开发并不是和传统手机开发一样,特别是焦点控制和用户操作体验风格上有很大的区别,本系列博文主要用TV播放器的实现去了解下在智能设备上的开发一个APP的流程,实现遥控器控制焦点移动,方向键模拟鼠标,并完成在线视频直播,手机当遥控器使用等相关功能。点击查看原文 ,转载请说明出处 :http://blog.csdn.net/sk719887916。
说到安卓TV上的APP应用,最主要还是看焦点控制,其他和手机APP无多大区别。比如常见的TV版本视频播放器,TV浏览器,以及电视游戏,都采用九宫格的UI视觉 demoUI如下
实现这个ui很容易,但是要实现遥控器上下左右控制并实现动画放大效果,到边缘进行翻页效果,很多同学就不知道怎么做了 ,看到很多人在手机上实现的手机UI很炫,但是貌似
没有一篇讲解TV或者电视盒子上应用开发的列子的,包括点击翻页,或者移动,在这个TV开发入门的文章中,本人以微小的技术给大家先说下安卓事件焦点机制,之后的几篇文章中,
本人将结合自己经验,详细说明安卓TV项目开发,安卓在线电视demo,实现一个TV上的视频应用,前提是要学会自定义view,,也要学会android事件机制,,必须先了解触控事件,
MotionEvent是必要,接下来本蝙给大家说下MotionEvent具体原理,,下篇将会说道键盘点击事件KeyEvent。
安卓主要点击事件
在android下,事件的发生是在监听器下进行,android系统可以响应按键事件和触摸屏事件,事件说明如下:
l onClick(View v) 一个普通的点击按钮事件
l onlongClick(View v) 一个普通的点击长按按钮事件
l boolean onKeyMultiple(int keyCode,int repeatCount,KeyEvent event)多个事件连续时发生,用于按键重复,必须重载@Override实现
l boolean onKeyDown(int keyCode,KeyEvent event) 用于在按键进行按下时发生
l boolean onKeyUp(int keyCode,KeyEvent event) 用于在按键进行释放时发生
l boolean onKeyLongPress(int keyCode, KeyEvent event)当你长时间按时发生
l onTouchEvent(MotionEvent event) 触摸屏事件,当触摸屏幕时发生(暂时简单的这么理解,后做详细说明)
l boolean dispatchTouchEvent(MotionEvent event) 触控时负责事件传递,必须重载@Override实现 (View和Activity都可以进行分发)
当然也有传递KeyEvent的方法
l boolean onInterceptTouchEvent(MotionEvent event) 触控时负责事件拦截,ViewGroup负责事件拦截。
Event事件机制
(1)Event事件的拦截
onInterceptTouchEvent(),安卓中此事件负责拦截一个用户产生的点击或者触摸事件,主要起终止传递作用,当用户点触摸产生一个事件时,由上层(view,Activity)传入事件时,此方法负责拦截,拦截后将交由本控件去消费当前事件,如果无需拦截,则继续交由下层的view去自己传递和分发。具体如下:
onInterceptHoverEvent() 也拥有拦截权利,但是它和OnInterCeptTouchEvent()有细微区别,此方法主要处理滑动事件,通俗讲就是当产生有位移的事件时(列如当我们的触摸事件由产生速率的时候)触发此方法。
(2)Event事件的传递
(3)Event事件响应
(4 (4 )Event传递整个过程
MotionEvent事件
一般我们是在View或者activty的重写onTouchEvent()方法中处理MotionEvent对象的.
public boolean onTouchEvent(MotionEvent event)
(1)MotionEvent事件的类型
主要的事件类型有:
ACTION_DOWN: 表示用户开始触摸.
ACTION_MOVE: 表示用户在移动(手指或者其他)
ACTION_UP:表示用户抬起了手指
ACTION_CANCEL:表示手势被取消了,一些关于这个事件类型的讨论见:http://stackoverflow.com/questions/11960861/what-causes-a-motionevent-action-cancel-in-android
还有一个不常见的:
ACTION_OUTSIDE: 表示用户触碰超出了正常的UI边界.
但是对于多点触控的支持,Android加入了以下一些事件类型.来处理,如另外有手指按下了,
有的手指抬起来了.等等:
ACTION_POINTER_DOWN:有一个非主要的手指按下了.
ACTION_POINTER_UP:一个非主要的手指抬起来了
可以通过getAction()可以获取类型,在android2.2之后加入多点触控支持之后使用getActionMasked()方法.
(2)事件发生的位置,x,y轴
getX() 获得事件发生时,触摸的中间区域在屏幕的X轴.
getY() 获得事件发生时,触摸的中间区域在屏幕的X轴.
在多点触控中还可以通过:
getX(int pointerIndex) ,来获得对应手指事件的发生位置. 获得Y轴用getY(int pointerIndex)
(3)其他属性
getEdgeFlags():当事件类型是ActionDown时可以通过此方法获得,手指触控开始的边界. 如果是的话,有如下几种值:EDGE_LEFT,EDGE_TOP,EDGE_RIGHT,EDGE_BOTTOM
特别说明:
(1)首先是MotionEvent 中getAction()与getActionMasked()的区别:
首先看源码:
1
2
3
4
5
6
7
8
9
10
11
12
|
public static final int ACTION_MASK = 0xff ; public final int getAction() { return mAction; } public final int getActionMasked() { return mAction & ACTION_MASK; } |
上面的代码是基于android2.2的,注释是android4.X中最新的.
他们有什么区别呢?如果mAction的值是在0x00到0xff之间的话。getAction()返回的值,和
getActionMasked()的返回的值是一样的。
(Q1)那什么时候返回的值是一样的呢?即当mAction值大于0xff时,那什么时候会大于0xff呢?
这就是是当有多点触控时。当有多点触控时。
mAction的低8位即0x00到0xff用来表示动作的类型信息。
例如:MotionEvent#ACTION_DOWN的值是 0,即0x00。
MotionEvent#ACTION_UP的值是 1,即0x01。
等等。
但是,我们知道Android是支持多点触控的,那么怎么知道这个一个MotionEvent是哪一个
触控点触发的呢?那么就还需要MotionEvent带有触控点索引信息。
Android的解决方案时在;mAction的第二个8位中存储。
例如,如果mAction的值是0x0000,则表示是第一个触控点的ACTION_DOWN操作。
如果mAction的值是0x0100呢,则表示是第二个触控点的ACTION_DOWN操作。
第三个的ACTION_DOWN呢?相信你可以推出来是0x0200。
总而言之,mAction时的低8位(也就是0-7位)是动作类型信息。
mAction的8-15位呢,是触控点的索引信息。(即表示是哪一个触控点的事件)。
(Q2),为什么不用两个字段来表示。
如 int mAction,int mPointer,
mAction表示动作类型,mPointer表示第几个触控点。点击查看原文
因为,动作类型只要0-255就可以了,动作类型,mPointer也是。
只要一个字段(32位),否则需要两个字段(32*2=64位),即可以节约内存。又可以方便提高处理速度。
不过通常我们都是以不同的字段来存储不同的信息。但是在计算机内部他们还是变成了0,1。
计算机始终还是以位来存储信息的。如果我们多我熟悉以位为基本单位来理解信息的存储。对于理解android中的很多变量是很有帮助的。因为他其中的很多东西使用的这样的节约内在的技巧。
如onMeasure中的MeasureSpec。(onMeasures是view绘制过程中常用的方法 具体过程请参考其他文章)
先看关于这两个方法注释:
我简单的翻译如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/** * action码的位掩码部分就是action本身 */ public static final int ACTION_MASK = 0xff ; /** 返回action的类型,考虑使用getActionMasked()和getActionIndex()来获得单独的经过掩码的action和触控点的索引. @return action例如ACTION_DOWN或者ACTION_POINTER_DOWN与转换的触控点索引的合成值 */ public final int getAction() { return mAction; } /** 返回经过掩码的action,没有触控点索引信息. 通过getActionIndex()来得到触控操作点的索引. @return action,例如ACTION_DOWN,ACTION_POINTER_DOWN */ public final int getActionMasked() { return mAction & ACTION_MASK; } |
在上面的两个方法中注释出现差异的地方是对于ACTION_POINTER_DOWN的描述:
通过getAction()返回的ACTION_POINTER_DOWN的是与转换触控点索引的合成值.
而getActionMasked()则就是一个ACTION_POINTER_DOWN的值:
这么来看我们知道一个action的代码值还包含了action是那个触控点的索引值:
现在我们对比来看看ACTION_MASK和ACTION_POINTER_INDEX_MASK
1
2
|
public static final int ACTION_MASK = 0xff ; public static final int ACTION_POINTER_INDEX_MASK = 0xff00 ; |
还没有看出来什么吗?
您把ACTION_MASK看成是0x00ff
就知道了吧.
也就是说,一个MotionEvent中的action代码,
前8位是实实在在包含表示哪一个动作常量.
后八位呢就是包含了触控点的索引信息.
因为ACTION_MASK = 0x00ff所以,经过ACTION_MASK掩码过后的action码就没有索引信息了.
如何得索引值呢?
原理:
先将action跟0xff00相与清除前8位用于存储动作常量的信息,
然后将action右移8位就可以得到索引值了.
我们就可以自己想办法得到索引信息了.
即先对action用ACTION_POINTER_INDEX_MASK进行掩码处理,
即 maskedIndex = action&ACTION_POINTER_INDEX_MASK = action&0xff00
这各掩码也就是将action这个数的前8位清零.
然后再将maskedIndex向右移8位就能够得到索引值了.
再看看android真实是怎么做的吧,
用于右移8位的常量.
1
2
3
4
5
|
/** * Bit shift for the action bits holding the pointer index as * defined by {<a href="http://my.oschina.net/link1212" target="_blank" rel="nofollow">@link</a> #ACTION_POINTER_INDEX_MASK}. */ public static final int ACTION_POINTER_INDEX_SHIFT = 8 ; |
再年得到索引值方法源代码,如下:
1
2
3
|
public final int getActionIndex() { return (mAction & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT; } |
为什么要有索引信息?
因为,这样说吧,android中,当有触摸事件发生时(假设已经注册了事件监听器),调用你注册监听器中的方法onTouch(,MotionEvent ev);传递了一个MotionEvent的对象过来.
但是,想想,上面只传递进来一个MotionEvent过来,如果只是单点触控那是没有问题.
问题就是当你多个手指触控的时候也是只传递这一个MotionEvent进来,
这个时候,你当然想知道每个手指的所对应的触控点数据信息啦.
所以MotionEvent中有就要索引信息了.
事件是你可以很容易通过API看到,MotionEvent还包含了移动操作中其它历史移动数据.
方便处理触控的移动操作.
android sdk对于这个类的描述中就有这么一句:
For efficiency, motion events with ACTION_MOVE may batch together multiple movement samples within a single object.
翻译下:"出于效率的考虑,事件代码为ACTION_MOVE的Motion,会在一个MotionEvent对象中包含多个移动数据采样."
现在我们对于MotionEvent有了初步的了解了。下篇将会讲到键盘事件安卓Tv开发(二)焦点控制(键盘事件),之后会即将实现以上UI,点击查看原文 ,用遥控器控制UI的View移动。
随之逐步完成所有功能。本文出处:http://blog.csdn.net/sk719887916/article/details/44780669
安卓Tv开发(一)移动智能电视之焦点控制(触控事件)的更多相关文章
- 安卓Tv开发(二)移动智能电视之焦点控制(按键事件)
原文:http://blog.csdn.net/sk719887916/article/details/44781475 skay 前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家 ...
- 安卓TV开发(九) Android模拟事件 遥控器变身成鼠标来操作TV
本文出处:http://blog.csdn.net/sk719887916/article/details/40348853,作者:skay 阅读此文建议先阅读 安卓Tv开发(二)移动智能电 ...
- 安卓TV开发(概述) 智能电视之视觉设计和体验分析
转载说明出处 :http://blog.csdn.net/sk719887916, 作者:skay 前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大 ...
- 安卓TV开发(十) 智能电视开发之在线视频直播
转载注明出处:http://blog.csdn.net/sk719887916/article/details/46582987 从<安卓TV开发(八) 移动智能终端多媒体之在线加载网页视频源& ...
- 安卓TV开发(四) 实现主流智能TV视频播放器UI
前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大量使用,但是这些设备上的开发并不是和传统手机开发一样,特别是焦点控制和用户操作体验上有很大的区别,本系列博文主 ...
- 安卓TV开发(三) 移动智能设备之实现主流TV电视盒子焦点可控UI
前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居,以及可穿戴设备的大量使用,但是这些设备上的开发并不是和传统手机开发一样,特别是焦点控制和用户操作体验上有很大的区别,本系列博文主 ...
- 安卓TV开发(五) 移动智能终端UI之实现主流TV焦点可控UI
载请标明出处:http://blog.csdn.net/sk719887916,作者:skay 由于其他网站收录,导致你无法查看本系列原创文章请点击此处 安卓TV开发(四)实现主流智能T ...
- 安卓TV开发(前言)— AndroidTV模拟器初识与搭建
原文:http://blog.csdn.net/sk719887916/article/details/39612577skay 前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家居 ...
- 安卓TV开发(八) 移动智能终端多媒体爬虫技术 获取加载网页视频源
转载请标明出处:http://blog.csdn.net/sk719887916/article/details/40049137,作者:skay 从上一篇学习中,学习了多媒体技术中的怎么去用josu ...
随机推荐
- 卷积神经网络的一些经典网络(Lenet,AlexNet,VGG16,ResNet)
LeNet – 5网络 网络结构为: 输入图像是:32x32x1的灰度图像 卷积核:5x5,stride=1 得到Conv1:28x28x6 池化层:2x2,stride=2 (池化之后再经过激活函数 ...
- 微信小程序开发-IP地址查询-例子
微信小程序开发 小程序搜索框 IP地址查询 搜索查询 样例 微信小程序 开发 参考 https://mp.weixin.qq.com/debug/wxadoc/dev/component/ ...
- disabled OR readonly
1.对元素设置disabled以及readonly属性 $("#uid").attr("disabled",true); $("#uid") ...
- 电力 Web SCADA 工控组态编辑器
前言 SVG 并非仅仅是一种图像格式, 由于它是一种基于 XML 的语言,也就意味着它继承了 XML 的跨平台性和可扩展性,从而在图形可重用性上迈出了一大步.如 SVG 可以内嵌于其他的 XML 文档 ...
- 关于 Rijndael 加密
MSDN https://msdn.microsoft.com/zh-cn/library/system.security.cryptography.rijndaelmanaged(v=vs.110) ...
- 【阿里聚安全·安全周刊】互联网时代人类还有被遗忘的权利吗 | Android与中兴
本周七个关键词:互联网时代丨中兴和Android丨安卓厂商和安全补丁丨移动支付安全丨泰国移动运营商泄密丨格式化硬盘的恶意程序丨代码签名滥用 -1- [互联网] 互联网时代 人类还有被遗忘的权利吗 ...
- 机器学习基石:16 Three Learning Principles
三个理论上界: 三个线性模型: 三个关键工具: 三条学习规则: 1.奥卡姆剃刀定律 先从简单模型开始, 训练后出现欠拟合, 再尝试复杂点模型. 2.采样误差 训练.验证.测试数据尽量同分布. 3.数据 ...
- [JLOI 2015]装备购买
Description 脸哥最近在玩一款神奇的游戏,这个游戏里有 n 件装备,每件装备有 m 个属性,用向量zi(aj ,.....,am) 表示 (1 <= i <= n; 1 < ...
- [SDOI 2010]魔法猪学院
Description 题库链接 给出一张 \(n\) 个点 \(m\) 条边有向图,询问最多有多少条不同的路径从 \(1\) 到 \(n\) 并且路径长度和 \(\leq E\) . \(2\leq ...
- [SDOI 2008]仪仗队
Description 作为体育委员,C君负责这次运动会仪仗队的训练.仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是 ...