在android中,有多种拦截用户与你的应用程序之间交互的方式.当考虑到你的用户接口事件,倾向是捕捉从具体的与用户交互的View对象中产生的Event.view类提 供了这些方法让你这样做.
随着,这么多的你可能用于组成你的布局的view 类,你可能注意到若干公共的看起来对用户接口事件有用的回调方法.这些方法当预期的action发生的发该对象上时,被称作android 的framework(框架).举例来说,当一个View(例如一个Button)被按下时,onTouchEvent()就被该对象调用.然而,为了拦截这个action,你必须扩展这个类,然后重写这个方法.然而,为了处理这样的event而扩展每一个View对象是不实用的.这就是为什么View类也包括一些巢状的接口(包含一些你能更容易定义的回调方法)的集合.这些接口,被称作
event listeners ,是你捕捉用户与你的UI之间交互的关键.
当你更加经常的实用这些event listeners 去监听用户的交互的时候,这里可能某个时候你想要扩展一个View 类,为了建立一个可定制的组件.可能,你想要扩展这个Button类,使某些事情更有趣.以防这种情况发生,你可以定义为你使用类的Event处理程序的类的默认Event行为 .
包括如下6种方法:
onClick()
View.OnClickListener
. 当被用户触碰或者轨迹球和按键的焦点在上面并按下了确定键的时候被调用.
onLongClick()
View.OnLongClickListener
. 当用户长时间的触碰一个item的时候或者轨迹球和按键的焦点在上面并按下了确定键一段时间后的时候被调用
onFocusChange()
View.OnFocusChangeListener
. 当用户的指向相对与当前焦点的其他item上的时候,被调用.
onKey()
View.OnKeyListener
. 当用户的焦点在一个item上并按下或松开一个按键的时候被调用.
onTouch()
View.OnTouchListener
. 当用户的操作被认定为依次触碰事件,包括在屏幕上的一次按下,或松开或者任何移动手势.
onCreateContextMenu()
View.OnCreateContextMenuListener
. 当一个上下文菜单被建立.具体更多信息请看 Creating Menus中对context menu的讨论.
这些方法是它们预期的接口的单独的存在(These methods are the sole inhabitants of their respective interface).为了定义这些方法中的一个,并处理的你Event,要实现你的Activity中的巢状接口或者把它定义成匿名类.然后传一个实例给你实现该接口的View.然后用set...Listener()
方法(例如,调用
OnClickListener接口的具体实现 ).setOnClickListener()方法,然后传给它你对
下面例子展示了如何为一个Button注册一个on-click listener
// Create an anonymous implementation of OnClickListener private OnClickListener mCorkyListener = new OnClickListener() { public void onClick(View v) { // do something when the button is clicked } }; protected void onCreate(Bundle savedValues) { ... // Capture our button from layout Button button = (Button)findViewById(R.id.corky); // Register the onClick listener with the implementation above button.setOnClickListener(mCorkyListener); ... }
你也可以找到更方便的实现 OnClickListener接口,作为你的Activity的一部分.下面代码可以避免额外的类加载和对象配额.代码如下:
public class ExampleActivity extends Activity implements OnClickListener { protected void onCreate(Bundle savedValues) { ... Button button = (Button)findViewById(R.id.corky); button.setOnClickListener(this); } // Implement the OnClickListener callback public void onClick(View v) { // do something when the button is clicked } ... }
注意,这个onClick()方法在上述例子中回调没有返回值.但是一些其他的Event监听方法必须返回一个布尔值.这个原因取决于具体的Event.少数原因如下.
onLongClick() - 这个方法返回一个布尔值,指示你是否已经consumed这个Event而且该方法不能被更远的运载.当返回true时,指示你已经处理了这个EVent事件而且它需要在这里停止.当返回false的时候,表示你还没有处理它或者这个Event需要被其他on-click监听者延续. ·
·onkey()- 这个方法返回一个布尔值,指示你是否已经consumed这个Event而且该方法不能被更远的运载.当返回true时,指示你已经处理了这个EVent事件而且它需要在这里停止.当返回false的时候,表示你还没有处理它或者这个Event需要被其他on-click监听者延续.
·onTouch()- 这个方法返回一个布尔值,指示你是否已经consumed这个Event.重要的是这个Event能够有多个action(互相之间连续的),所以,如果当你让按抓动作event被接收的时候返回false.你就指示你还没有consumed这个event,而且也不对这个event的子队列中的action产生作用.Thus, you will not be called for any other actions within the event, such as a finger gesture, or the eventual up action event.(实在不知道怎么翻译好,我只在初中当过两年英语课代表).
如果你创建一个为View定制的组件,那么你就必须定义若干使用默认event handler的回调方法.常见多的回调方法包括:
onKeyDown(int, KeyEvent)
- Called when a new key event occurs.onKeyUp(int, KeyEvent)
- Called when a key up event occurs.onTrackballEvent(MotionEvent)
- Called when a trackball motion event occurs.onTouchEvent(MotionEvent)
- Called when a touch screen motion event occurs.onFocusChanged(boolean, int, Rect)
- Called when the view gains or loses focus. 这里也有一些其他的方法你需要注意的.那些不是View 类的组成部分.但是可以直接影响你处理event的方式.所以,当管理更多复杂的Event在一个布局里的时候,考虑这些其他的方法.
Activity.dispatchTouchEvent(MotionEvent)
- 允许你的activity 在所有touch event传送到窗口之前拦截它们.ViewGroup.onInterceptTouchEvent(MotionEvent)
- 允许一个View组,监控看管event在它们被传送到子View的时候.ViewParent.requestDisallowInterceptTouchEvent(boolean)
- Call this upon a parent View to indicate that it should not intercept touch events with 当一个用户正在导航一个UI用直接的按键或者一个轨迹球的时候,很有必要给,可操作的items焦点.这样用户就能看到哪些能接收输入操作.如果这个设备是可触碰的,而且用户开始用touch的方式与UI进行交互,那样就不在需要显示出高亮的items,或者给一个特殊的view焦点.因而,这种模式叫做"touch mode".
对一个可触碰的设备来说,一旦用户碰触屏幕,设备就会进入"touch mode".从前面的观点看,只有那些用 isFocusableInTouchMode()
能返回true的Views,比如文本编辑器.其他Views也是可触碰的,像Button,当被触碰后不会获得焦点,它们仅仅只会转向它们的on-click listener.
任何时候一个用户直接按键或用轨迹球滑动,设备都会退出"touch mode",而且找到一个获得焦点的view.现在,用户可以不碰屏幕就恢复用UI的交互.
这个"touch mode' 的状态在这个系统中都被保持着(所有的windows 和activities).要查询这个当前状态,你可以调用 isInTouchMode()方法看设备当前是否在"touch mode"下.
框架会有规律的处理焦点的移动用于回馈用户的输入.它包括当Views被移除或隐藏的时候改变焦点,或者 新View可用的时候.Views指示了它们从
方法获得焦点意愿.要改变一个View是否可以接受焦点,调用 isFocusable()
方法.当在触摸模式的时候.你可以用 setFocusable()
查询一个View是否允许焦点.或者用isFocusableInTouchMode()
改变它.setFocusableInTouchMode()
焦点移动是根据一种在给定的方向找到最近的邻居的计算系统确定的.在很少的情况下,默认的算法可能跟开发者的intend行为不匹配,在这种情况下,你能提供显示的重写,在layout布局文件中的如下属性中nextFocusDown , nextFocusLeft , nextFocusRight , and nextFocusUp .用以上xml属性.增加其中的一个属性给那些将要失去焦点的View.定义这个属性的值,为特定的View的id(需要给定焦点的View).例子代码:
<LinearLayout android:orientation="vertical" ... > <Button android:id="@+id/top" android:nextFocusUp="@+id/bottom" ... /> <Button android:id="@+id/bottom" android:nextFocusDown="@+id/top" ... /> </LinearLayout
通常,在这种垂直布局中,从第一个按钮导向将不会到离开,也不会导向到第二个按钮.现在这个top button已经用nextFocusUp(反之也是) 定义了这个bottom的按钮,这个导向焦点会从上到下然后再从下到上循环.
如果你想要声明一个View在你的UI中为可获焦点的(传统的不是).增加android:focusable属性给这个VIEW在你的xml属性中.设置这个值为true.你也可以声明一个VIEW为可获焦点的,当在"touch mode"下,用
android:focusableInTouchMode
属性.
要想使得一个特定的View获得焦点,调用
方法.requestFocus()
要监听焦点事件(当一个View失去获获得焦点被通知),用
Event Listeners部分讲的那样. onFocusChange()方法,就像前面
这篇是,文档学习的第三篇.因为发现好多都练习过 了就没写代码.希望读者原谅.然后基本上文档的内容都翻译了下.觉得文档已经很简略了,如果要再简略就会失去了意义.在学习文档的时候也发现自己的语言组织能力和口头表达能力还有英语词汇量有待提高.昨天,买的MOTO DEFY终于到了.花了几个小时的时间去玩转它.发现比模拟的感觉好多了.真是好奇妙!今天在看文档的过程中还发现了一个很好的创意,用于开发应用的创意.希望我的应用到时也能像现在的Angry Bird一样给我带来一些....东西吧,呵呵.期待中...提高中...