Android UI Event Listener

处理UI事件

 

在android上, 有多种方法获取用户与应用程序的交互信息. 当考虑UI内部的事件时, 咱们的方法是抓取特定的与用户交互的View对象产生的事件. android

 

在你用来组成布局的View对象中,你可能会注意到一些用于处理UI事件的回调函数. 这些方法是被Android框架调用的. 例如,当一个View被按下时, 它的onTouchEvent()方法被调用. 可是,为了截获这个信息,你必须扩展这个类并改写这个方法. 而扩展每一个View对象来处理这样的事件多是不实际的. 这就是为何View类还包含一组你能够更方便定义的嵌套接口. 这些接口被称为监听器, 它们是你用来抓取用户动做的利器. 算法

 

虽然你可能更加经常使用事件监听器来监听用户动做, 有时候你可能确实但愿经过扩展一个View类的方法来作这一点. 可能你但愿扩展Button类来作一些巧妙的事情. 在这个状况下, 你可以使用时间处理器来定义该类的默认的事件行为. 框架

Event Listeners 事件监听器

 

一个事件监听器是View类的一个接口. 该接口包含的方法会在View注册的事件监听器被触发时被Android调用. 函数

 

在事件监听器中有下列方法: 布局

 

 

  • onClick() 位于View.OnClickListener中. 在用户触摸该对象,或者使用轨迹球等使该对象得到焦点, 并按下"enter"键或者按下轨迹球时被调用.
  • onLongClick() 位于 View.OnLongClickListener中. 在用户按住该元素,或者按住轨迹球时调用.
  • onFocusChange() 位于 View.OnFocusChangeListener中. 该对象得到或失去焦点时调用.
  • onKey() 位于 View.OnKeyListener中. 在该对象得到焦点,而且按下一个键时调用.
  • onTouch() View.OnTouchListener. 当用户在View对象的范围内进行一个触摸动做时. 例如按下,放开,或者任何的移动手势.
  • onCreateContextMenu() View.OnCreateContextMenuListener. 当一个快捷菜单被显示时(当用户长按).

这些方法只是它们对应接口的惟一方法. 为了定义这些方法, 能够在你的Activity中实现这个接口, 也可使用一个匿名类. 而后, 将实现该接口实例传给对应的View.set...Listener方法. ui

以OnClickListener为例: this

// 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);
    
...
}
spa

 

你可能以为将OnClickListener 实现为activity的一部分会更加方便. 这能够避免额外的类. 例如: .net

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
    
}
    
...
}
component

 

注意 onClick() 没有返回值, 但有些事件监听器必须有一个布尔返回值. 下面是一些缘由:

  • onLongClick() - 返回一个布尔值表示你是否消耗了该event. 也就是,若是你已经处理了该event, 则它应该中止了,就返回true, 而若是你没有处理它,而是将它留给其它的on-click监听器, 则返回false.
  • onKey() - 同上.
  • onTouch() - 返回一个布尔值表示你是否消耗了该event. 该event能够有多个动做. 若是在向下的动做接收时你返回false, 就表示你没有消耗该event, 而且对后续动做也不感兴趣. 也就是说, 后面的手势动做,以及最后的向上动做都将不会再被通知.

 

键事件永远会被发送到当前得到焦点的View. 它们是从View层次的顶端开始分派, 而后向下直到合适的目的地. 若是你的View如今拥有焦点, 那么你能够从dispatchKeyEvent()方法中看到事件的分派过程. 除了使用veiw以外,你也可使用你的Activity的onKeyDown()和onKeyUp()方法来获取全部的时间.

 

注意: Android将首先调用事件处理器, 而后调用合适的默认处理器. 所以, 从这些事件监听器中返回true将使其它监听器和默认处理器失效. 所以在你返回true时要当心.

Event Handlers 事件处理器

 

若是你从View来建立一个自定义的component,那么你能够定义一些默认事件处理器。在 Building Custom Components文档中,你将看到这些回调函数:

  • onKeyDown(int, KeyEvent) -当一个新的键盘时间开始被调用。
  • onKeyUp(int, KeyEvent) -当一个键被释放时调用。
  • onTrackballEvent(MotionEvent) -当轨迹球移动时调用。
  • onTouchEvent(MotionEvent) - 当屏幕发生移动事件时调用。
  • onFocusChanged(boolean, int, Rect) -当一个View丢失焦点时调用。

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

  • Activity.dispatchTouchEvent(MotionEvent) -能够在这些事件被分派到窗口以前让Activity截获全部的事件。
  • ViewGroup.onInterceptTouchEvent(MotionEvent) -让ViewGroup在事件分派到子View以前看到这些事件。
  • ViewParent.requestDisallowInterceptTouchEvent(boolean) - 让父View不要使用onInterceptTouchEvent(MotionEvent)来截获event.

Touch Mode 触摸模式

 

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

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

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

Handling Focus 处理焦点

 

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

 

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

<LinearLayout
    
android:orientation="vertical"
    ... 
>
  
<Button android:id="@+id/top"
          
android:nextFocusUp="@+id/bottom"
          ... 
/>
  
<Button android:id="@+id/bottom"
          
android:nextFocusDown="@+id/top"
          ... 
/>
</LinearLayout>

 

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

若是你但愿将一个View设为可获取焦点,那么加入xml属性android:focusable="true" 和android:focusableInTouchMode = "true".

 

但愿一个View得到焦点时,调用requestFocus().

 

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

http://blog.csdn.net/lmhit/article/details/5576246

相关文章
相关标签/搜索