Android(安卓)事件处理
以下 3 个概念与 Android 事件管理相关:
- 事件监听:事件侦听器是
View
类中包含单个回调方法的接口。当用户与 UI 中的项目交互触发侦听器注册到的视图时,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 种方法,您可以根据情况使用其中任何一种。
- 使用匿名内部类
Activity
类实现Listener
接口。- 使用布局文件 activity_main.xml 直接指定事件处理程序。
以下部分将为您提供所有 3 种场景的详细实例:
触摸模式
用户可以通过使用硬件键或按钮或触摸屏幕与设备交互。触摸屏幕可使设备进入触摸模式。然后,用户可以通过触摸屏幕上的虚拟按钮、图像等与设备交互。您可以通过调用 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 活动的私有数据。无需引用即可调用活动。
但是,如果将处理程序应用于多个控件,则必须剪切并粘贴处理程序的代码,如果处理程序代码很长,则代码更难维护。
以下是简单的步骤,说明我们将如何使用单独的 Listener
类来注册和捕获单击事件。类似的方式,您可以为任何其他必需的事件类型实现监听器。
步骤 | 描述 |
---|---|
1 | 您将使用 Android studio IDE 创建一个 Android 应用程序,并将其命名为 com.example.myapplication 包下的 myapplication,如 Hello World 实例一章所述。 |
2 | 修改 src/MainActivity.java 为定义的两个按钮添加单击事件监听器和处理程序的文件。 |
3 | 修改 res/layout/activity_main.xml 内容包含 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
表示 logo
<?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 运行应用程序,请打开项目的 activity 文件之一,然后单击工具栏上的运行 Eclipse 图标。Android studio 在您的 AVD 上安装应用程序并启动它,如果您的设置和应用程序一切正常,它将显示以下模拟器窗口:
现在,您尝试逐个单击两个按钮,您会看到 Hello World 文本的字体将发生变化,这是因为注册的单击事件处理程序方法正在针对每个单击事件调用。
练习
建议尝试为不同的事件类型编写不同的事件处理程序,并了解不同事件类型及其处理的确切差异。与菜单、微调器、选择器小部件相关的事件差别不大,但它们也基于与上面解释的相同的概念。