android下,事件的发生是在监听器下进行,android系统可以响应按键事件和触摸屏事件,事件说明如下:

onClick(Viewv)一个普通的点击按钮事件

booleanonKeyMultiple(intkeyCode,intrepeatCount,KeyEventevent)用于在多个事件连续时发生,用于按键重复,必须重载@Override实现

booleanonKeyDown(intkeyCode,KeyEventevent)用于在按键进行按下时发生

booleanonKeyUp(intkeyCode,KeyEventevent)用于在按键进行释放时发生

onTouchEvent(MotionEventevent)触摸屏事件,当在触摸屏上有动作时发生

booleanonKeyLongPress(intkeyCode,KeyEventevent)当你长时间按时发生

当屏幕中包含一个ViewGroup,而这个ViewGroup又包含一个子view,这个时候android系统如何处理Touch事件呢?到底是ViewGroup来处理Touch事件,还是子view来处理Touch事件呢?

android系统中的每个View的子类都具有下面三个和TouchEvent处理密切相关的方法:

1publicbooleandispatchTouchEvent(MotionEventev)这个方法用来分发TouchEvent

2publicbooleanonInterceptTouchEvent(MotionEventev)这个方法用来拦截TouchEvent

3publicbooleanonTouchEvent(MotionEventev)这个方法用来处理TouchEvent

有一些不属于View,但是也能直接影响到事件处理的方法:

Activity.dispatchTouchEvent(MotionEvent)-可以在这些事件被分派到窗口之前让Activity截获所有的事件。

ViewGroup.onInterceptTouchEvent(MotionEvent)-ViewGroup在事件分派到子View之前看到这些事件。

ViewParent.requestDisallowInterceptTouchEvent(boolean)让父View不要使用onInterceptTouchEvent(MotionEvent)来截获event.

一个ViewGroup是一个可以包含其他view的特别的View(是View的子类),ViewGroup是各个LayoutView组件的基类,这个类还定义了LayoutParams类来指定这个基类的布局参数。

1)事件的初始触发者是父组件(LinearLayout),父组件有权决定是分发这个事件还是拦截这个事件;

2)如果父组件分发这个事件,则子控件会收到这个事件,子控件调用onTouchEvent方法处理事件,如果onTouchEvent返回的是false,则事件还会交给父组件处理。

总结论是:

Android的触摸事件分发是从最上层的Activity开始的,然后dispatch到子View,当分发到触发事件的View时,再逐层往回调用onTouchEvent函数,下面是实例代码。

TouchEvent发生时,首先ActivityTouchEvent传递给最顶层的ViewTouchEvent最先到达最顶层viewdispatchTouchEvent,然后由dispatchTouchEvent方法进行分发,如果dispatchTouchEvent返回true,则交给这个viewonTouchEvent处理,如果dispatchTouchEvent返回false,则交给这个viewinterceptTouchEvent方法来决定是否要拦截这个事件,如果interceptTouchEvent返回true,也就是拦截掉了,则交给它的onTouchEvent来处理,如果interceptTouchEvent返回false,那么就传递给子view,由子viewdispatchTouchEvent再来开始这个事件的分发。如果事件传递到某一层的子viewonTouchEvent上了,这个方法返回了false,那么这个事件会从这个view往上传递,都是onTouchEvent来接收。而如果传递到最上面的onTouchEvent也返回false的话,这个事件就会消失,而且接收不到下一次事件。

综上结论:

1种情况L.onInterceptTouchEvent=false&&L.onTouchEvent=true&&T.onTouchEvent=true结论:TouchEvent完全由TextView处理。

2种情况L.onInterceptTouchEvent=false&&L.onTouchEvent=true&&T.onTouchEvent=false结论:TextView只处理了ACTION_DOWN事件,LinearLayout处理了所有的TouchEvent

3种情况L.onInterceptTouchEvent=true&&L.onTouchEvent=true结论:LinearLayout处理了所有的TouchEvent

4种情况L.onInterceptTouchEvent=true&&L.onTouchEvent=false结论:LinearLayout只处理了ACTION_DOWN事件,那么其他的TouchEvent被谁处理了呢?答案是LinearLayout最外层的Activity处理了TouchEvent

TouchMode触摸模式

但一个用户使用方向键或者轨迹球来在UI上移动时,需要让可动作的UI元素获得焦点,这样用户可以看到什么东西将获得他们的输入。如果设备具有触摸能力,用户使用触摸的方式来交互,那么就没有必要给一个元素焦点。因此,有一种交互的模式叫做触摸模式

对于一个可触摸的设备,一旦用户触摸了屏幕,设备就进入触摸模式。在这以后,只有isFocusableInTouchMode()为真的View是可以获得焦点的,例如文本框。其它的View可以触摸,例如按钮,在触摸的时候不会获得焦点。它们只是启动对应的on-click监听器。在用户按下方向键或者旋转轨迹球时,设备将退出触摸模式,并寻找一个view并使他获得焦点。现在,用户可以不触摸屏幕来交互。

触摸模式状态在整个系统中被维护。你可以使用isInTouchMode()来查询当前状态。

HandlingFocus处理焦点

android框架会根据用户输入来处理焦点的移动。这包含了在View被移除或隐藏或再次出现时改变焦点。View使用isFocusable()setFocusable()方法来表示和设置它们能否获得焦点。在触摸模式下,可以使用isFocusableInTouchMode()setFocusableInTouchMode().

焦点移动时基于在某方向上最近距离元素的算法。在很少见的情形下,默认的算法可能和开发者的想法不一样。在这种情况下,你可以提供一个算法,修改以下几个xml属性:nextFocusDown,nextFocusLeft,nextFocusRightnextFocusUp.

一般来说,在这个竖直向下的布局中,从第一个按钮向上不会走到哪里。加入上述代码后,从第一个按钮向上会使第二个按钮获取焦点。

如果你希望将一个View设为可获取焦点,那么加入xml属性android:focusable=trueandroid:focusableInTouchMode=true.

希望一个View获得焦点时,调用requestFocus().

要监听焦点事件,使用onFocusChange()

更多相关文章

  1. android跑马灯效果实现(一直滚动不受影响)
  2. ListView与Button的共存问题解决
  3. android 给动画添加结束监听事件
  4. [已解决]Android(安卓)ListView EditView 获取焦点问题
  5. [qualcomm android] sim card status processing
  6. android开发之滑动效果实现图片浏览_ViewFilpper的使用
  7. Android事件分发机制——View(一)
  8. Android(安卓)ListView/ListActivity点击长按事件
  9. Android(安卓)ActionBar使用方法

随机推荐

  1. Android(安卓)MVVM
  2. 你的Android(安卓)HTTPS真的安全吗?
  3. Android(安卓)TextView实现逐字动画
  4. Android自定义View之贝塞尔曲线图
  5. Android万能下拉刷新,上拉加载。支持自定
  6. 在cocos2dx里访问/互调android里的activi
  7. Android:属性scaleType与图片的显示
  8. Android(安卓)Studio Git初体验
  9. Android(安卓)Log系统详解
  10. 【Android游戏开发十六】Android(安卓)Ge