Android - 事件处理
事件是收集有关用户与应用程序的交互式组件交互的数据的有用方法。 像按钮按下或屏幕触摸等。Android 框架维护一个事件队列作为先进先出 (FIFO) 基础。 您可以在程序中捕获这些事件并根据要求采取适当的措施。
Android 事件管理相关的概念有以下三个 −
事件监听器 − 事件监听器是 View 类中的一个接口,它包含一个回调方法。 当用户与 UI 中的项目交互触发已注册侦听器的 View 时,Android 框架将调用这些方法。
事件监听器注册 − 事件注册是事件处理程序向事件侦听器注册的过程,以便在事件侦听器触发事件时调用处理程序。
事件处理程序 − 当一个事件发生并且我们已经为该事件注册了一个事件监听器时,该事件监听器调用事件处理程序,这是实际处理该事件的方法。
事件监听器 & 事件处理程序
| 事件处理程序 | 事件监听器 & 描述 |
|---|---|
| onClick() | OnClickListener() 当用户单击或触摸或关注任何小部件(如按钮、文本、图像等)时调用此方法。您将使用 onClick() 事件处理程序来处理此类事件。 |
| onLongClick() | OnLongClickListener() 当用户点击或触摸或关注任何小部件(如按钮、文本、图像等)一秒或多秒时调用此方法。 您将使用 onLongClick() 事件处理程序来处理此类事件。 |
| onFocusChange() | OnFocusChangeListener() 当小部件失去焦点时调用它,即用户离开视图项。 您将使用 onFocusChange() 事件处理程序来处理此类事件。 |
| onKey() | OnFocusChangeListener() 当用户专注于项目并按下或释放设备上的硬件键时调用此方法。 您将使用 onKey() 事件处理程序来处理此类事件。 |
| onTouch() | OnTouchListener() 当用户按下按键、释放按键或屏幕上的任何移动手势时调用此函数。 您将使用 onTouch() 事件处理程序来处理此类事件。 |
| onMenuItemClick() | OnMenuItemClickListener() 当用户选择一个菜单项时调用它。 您将使用 onMenuItemClick() 事件处理程序来处理此类事件。 |
| onCreateContextMenu() | onCreateContextMenuItemListener() 这在构建上下文菜单时调用(作为持续"长按"的结果) |
作为 View 类的一部分,还有更多可用的事件侦听器,例如您的应用程序可能需要的 OnHoverListener、OnDragListener 等。因此,如果您要开发复杂的应用程序,我建议您参考 Android 应用程序开发的官方文档。
事件监听器注册
事件注册是事件处理程序向事件侦听器注册的过程,以便在事件侦听器触发事件时调用处理程序。虽然有几种棘手的方法可以为任何事件注册事件侦听器,但我将仅列出前 3 种方法,您可以根据情况使用其中任何一种。
使用 Anonymous 匿名内部类
Activity 类实现了 Listener 接口。
使用 Layout 文件 activity_main.xml 直接指定事件处理器。
以下部分将为您提供所有三个场景的详细示例 −
触控模式
用户可以通过使用硬件键或按钮或触摸屏幕与他们的设备进行交互。触摸屏幕使设备进入触摸模式。然后,用户可以通过触摸屏幕上的虚拟按钮、图像等与其进行交互。您可以通过调用 View 类的 isInTouchMode() 方法来检查设备是否处于触摸模式。
获得焦点
视图或小部件通常在获得焦点时突出显示或显示闪烁的光标。 这表明它已准备好接受用户的输入。
isFocusable() − 它返回 true 或 false
isFocusableInTouchMode() − 检查视图是否在触摸模式下可聚焦。 (使用硬件键时视图可能是可聚焦的,但在设备处于触摸模式时不能聚焦)
android:foucsUp="@=id/button_l"
onTouchEvent()
public boolean onTouchEvent(motionEvent event){
switch(event.getAction()){
case TOUCH_DOWN:
Toast.makeText(this,"you have clicked down Touch button",Toast.LENTH_LONG).show();
break();
case TOUCH_UP:
Toast.makeText(this,"you have clicked up touch button",Toast.LENTH_LONG).show();
break;
case TOUCH_MOVE:
Toast.makeText(this,"you have clicked move touch button"Toast.LENTH_LONG).show();
break;
}
return super.onTouchEvent(event) ;
}
事件处理示例
使用匿名内部类注册事件监听器
在这里,您将创建侦听器的匿名实现,如果每个类仅应用于单个控件并且您有优势将参数传递给事件处理程序,这将非常有用。在这种方法中,事件处理程序方法可以访问 Activity 的私有数据。 调用 Activity 不需要引用。
但是,如果您将处理程序应用于多个控件,则必须剪切和粘贴处理程序的代码,并且如果处理程序的代码很长,则会使代码更难维护。
以下是展示我们如何使用单独的 Listener 类来注册和捕获点击事件的简单步骤。 类似的方式,您可以为任何其他所需的事件类型实现您的侦听器。
| 步骤 | 描述 |
|---|---|
| 1 | 您将使用 Android Studio IDE 创建一个 Android 应用程序,并将其命名为 myapplication 在包 com.example.myapplication 下,如 Hello World 示例 一章中所述。 |
| 2 | 修改 src/MainActivity.java 文件,为定义的两个按钮添加点击事件监听器和处理程序。 |
| 3 | 修改 res/layout/activity_main.xml 文件的 detault 内容以包含 Android UI 控件。 |
| 4 | 无需声明默认字符串常量。Android Studio 会处理默认常量。 |
| 5 | 运行应用程序以启动 Android 模拟器并验证应用程序中所做更改的结果。 |
以下是修改后的主活动文件src/com.example.myapplication/MainActivity.java的内容。该文件可以包含每个基本生命周期方法。
package com.example.myapplication;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends ActionBarActivity {
private ProgressDialog progress;
Button b1,b2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progress = new ProgressDialog(this);
b1=(Button)findViewById(R.id.button);
b2=(Button)findViewById(R.id.button2);
b1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView txtView = (TextView) findViewById(R.id.textView);
txtView.setTextSize(25);
}
});
b2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView txtView = (TextView) findViewById(R.id.textView);
txtView.setTextSize(55);
}
});
}
}
以下是 res/layout/activity_main.xml 文件的内容 −
这里 abc 表示关于 tutorialspoint 的标志
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Event Handling "
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textSize="30dp"/>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tutorials point "
android:textColor="#ff87ff09"
android:textSize="30dp"
android:layout_above="@+id/imageButton"
android:layout_centerHorizontal="true"
android:layout_marginBottom="40dp" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton"
android:src="@drawable/abc"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Small font"
android:id="@+id/button"
android:layout_below="@+id/imageButton"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Font"
android:id="@+id/button2"
android:layout_below="@+id/button"
android:layout_alignRight="@+id/button"
android:layout_alignEnd="@+id/button" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="@+id/textView"
android:layout_below="@+id/button2"
android:layout_centerHorizontal="true"
android:textSize="25dp" />
</RelativeLayout>
以下将是 res/values/strings.xml 的内容来定义两个新常量 −
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">myapplication</string> </resources>
以下是 AndroidManifest.xml 的默认内容 −
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication" >
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.myapplication.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
让我们尝试运行您的 myapplication 应用程序。 假设您在进行环境设置时已经创建了 AVD。要从 Android Studio 运行应用程序,请打开项目的活动文件之一,然后单击工具栏中的 Run
图标。 Android Studio 在您的 AVD 上安装应用程序并启动它,如果您的设置和应用程序一切正常,它将显示以下 Emulator 窗口 −
现在您尝试一个一个地单击两个按钮,您将看到 Hello World 文本的字体会发生变化,这是因为每个单击事件都会调用已注册的单击事件处理程序方法。
练习
我会建议尝试为不同的事件类型编写不同的事件处理程序,并了解不同事件类型及其处理的确切差异。 与菜单、微调器、选择器小部件相关的事件略有不同,但它们也基于上述相同的概念。

