> 在用户的交互中,有不止一种的方法来截获事件。考虑到在用户界面中的事件时,从特殊的与用户交互的view对象中捕获事件,View类提供了一些特殊的方法。 再各种的视图类中,你要编写自己的布局,你可以声明一些公共的回调方法来响应UI事件。当相应的动作发生时,这些方法会被android框架自动调用。例如,当一个view被触摸时,onTouchEvent()方法被调用。然而,为了截获这些方法,我们需要重写这些方法。当然了,重写每一个这样的方法显然时不实际的,这就是为什么为何view类会有一些必须的接口这样你可以更加容易的使用。这些接口,被称作事件监听器 event listeners,这就是捕捉到界面上用户操作的关键。 当你经常在用户交互上使用事件监听器时,有时需要自己写一个继承自view的类,来自定义一个部件。如果你想继承一个Button类来实现更多的功能,这种情况下,你可以借助event handlers 类来定义默认的事件处理类。 事件监听器是包含简单回调方法的view类的一个接口,当用户触发了一些注册过的事件时,android系统框架会自动调用相应的方法。 事件监听器包含以下几个方法: onCLick() 来自View.onClickListener。 当view被触摸,或者焦点在view上时,用户按了确认键或导航键。 onLongClick() 来自 View.onLongClickListener。当view被触摸超过1秒,或者焦点在view上,用户按了确认或导航键超过1秒时,方法被调用。 onFocysChange() 来自 View.onFocusChangeListener。当焦点离开view时被调用。 onKey() 来自 View.onKeylistener。按下或者弹起某个键时方法被调用。 onTouch() 来自 View.OnTouchListener。当用户操作屏幕时被调用,包括按下释放或者其他的操作。 onCreateContextMenu() 来自 View.onCreateContextMenuListener。当一个Context Menu菜单被建立时调用。 这些方法都有自己的接口方法。如果想定义这些方法来处理自己的事件,只要在activity里面使用匿名类即可。然后使用View.setXXXListener()方法,将匿名类传递给view。 下面的例子演示了怎样给一个Button注册一个监听器:
- // 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);
...
}
复制代码你会发现让activity实现监听器接口是非常方便的,他可以让你的程序避免多余的对象分配。 - [size=14px]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
}
...
} [/size]
复制代码注意,上面例子中的onClick()回调方法没有返回值,但其他的时间监听器必须返回一个boolean类型的返回值,这是由监听器的类型决定的,例如:onLongClick()这个方法会返回一个布尔值,来说明这个事件正在进行,也就是说,返回true表明此事件正在被处理不会被继续传递了。onKey()也会返回一个布尔值,返回true的话说明此按键事件将会被处理并不会被继续响应。如果你没有处理或者希望事件继续被其他监听器响应,那么返回false。onTouch()返回同上,也是返回true就不再被传递。重点是有很多类型的事件与这个事件有关,例如,当接收到键被按下的事件时,如果你此时返回false,那么表明你将不会处理这个按键事件。因此,你不会处理这个事件,例如手势或者其他后续事件。记住这些按键事件总会让当前veiw成为当前焦点,他们从view层次结构的顶端开始被一级级传递,直到到达应该被响应的地方。如果你的view或者子view当前拥有焦点,那么你可以看到事件怎样传递到dispatchKeyEvent()方法。作为一种捕捉按键事件的替代方法,你可以接收activity里的所有的onKeyDown()和onKeyUp()事件。注意:Android会首先调用事件处理程序,然后再调用自定义的事件处理类。例如:返回true将会阻止事件被继续传递给下一层,也会阻止系统做一些默认的处理,所以如果你确定要终止这个事件就返回true。 如果你创建了一个自定义的view组件,那么你要定义几种回调方法来。在Building Custom Components文档中,你会学习到以下几个回调事件:onKeyDown(int,ketEvent);键被按下onKeyUp(int,keyEvent);键弹起onTrackballEvent(MotionEvent);轨迹球事件onTouchEvent(MotionEvent);触摸屏幕事件onFocusChanged(boolean,int,Rect);焦点改变事件这里有一些你需要知道的方法,他们不是view类的一部分,但是会直接影响到你对事件的处理。所以遇到十分复杂的布局时,可以考虑以下的几个方法:Activity.dispatchTouchEvent(MotionEvent)它允许你的activity拦截所有的触摸事件ViewGroup.onInterceptTouchEvent(MotionEvent)允许VeiwGroup来观察子view的事件ViewParent.requestDisallowInterceptTouchEvent(boolean)告诉父View不应该使用相关方法来拦截事件。
当用户正在使用导航键或者轨迹球来与手机交互时,有必要给当前互动的item例如button一个焦点,来让用户看到接收输入、或者说当前的控件。如果一个设备支持触摸,那么操作时就不需要用上面的高亮显示的方式来告诉用户。因此,便有了这种触摸模式。对于有触摸功能的设备来说,一旦用户触摸了屏幕,设备便会进入触摸模式。只有那些isFocusableInTouchMode()返回true的控件才可以获得焦点,例如文本编辑框。别的view是touchable的,例如按钮,但被点击时不会显示焦点。当被按下时,他们的事件监听器将会无效。任何时候用户点击了导航键或者轨迹球,设备都会退出touch模式,并且找一个view来显示焦点。现在,用户可以不用触摸屏幕来与设备进行交互了。Touch模式存在于整个系统中。包括窗口和activity。可以用isinTouchMode()方法来查询当前模式。
框架会处理常规的焦点改变事件来响应用户的输入。包括一些veiw的显示和隐藏。view通过isFocusable()方法来设定是否可以得到焦点。调用setFocusable()方法可以改变focusable状态。当view在触摸模式,你可以通过调用isFocusableInTouchMode()方法查询到是否支持,通过setFocusableInTouchMode()来设置。焦点的运动是根据给定方向最近的一个view来确定的。在极少情况下,默认的这种算法或许不符合开发者预期的要求。这种情况下,可以通过xml来明确确定焦点的转移情况。例如: - <LinearLayout
android:orientation="vertical"
... >
<Button android:id="@+id/top"
android:nextFocusUp="@+id/bOTTom"
... />
<Button android:id="@+id/bottom"
android:nextFocusDown="@+id/top"
... />
</LinearLayout>
复制代码一般的,在垂直的布局里,往下或者往上移动轨迹球或是导航键多不能移动焦点,现在可以通过xml的定义来达到移动焦点的目的。如果你想要声明可以获得焦点的view,可以在xml里添加android:focusable这个属性,设置为true,你也可以在Touch模式下添加android:focusableInTouchMode。使用requestFocus()方法可以使一个特定的师徒取的焦点。使用onFocusChange()方法来监听焦点事件。
|