• Android Video Tutorials

Android - 事件处理



事件是收集用户与应用程序交互式组件交互数据的一种实用方法。例如按钮按下或屏幕触摸等。Android 框架维护一个事件队列,采用先进先出 (FIFO) 的方式。您可以在程序中捕获这些事件,并根据需要采取相应的操作。

以下三个概念与 Android 事件管理相关:

  • 事件监听器 - 事件监听器是 View 类中的一个接口,包含单个回调方法。当向其注册监听器的 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 应用程序开发的官方文档。

事件监听器注册

事件注册是事件处理程序与事件监听器注册的过程,以便在事件监听器触发事件时调用处理程序。虽然有几种棘手的注册事件监听器的方法,但我只列出三种最佳方法,您可以根据情况使用其中任何一种。

  • 使用匿名内部类

  • Activity 类实现 Listener 接口。

  • 使用布局文件 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 应用程序,并在包 `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 指的是 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 中运行该应用程序,请打开项目的活动文件之一,然后单击工具栏中的运行 Eclipse Run Icon 图标。Android Studio 将应用程序安装到您的 AVD 并启动它,如果您的设置和应用程序一切正常,它将显示以下模拟器窗口:

Android Event Handling

现在尝试依次单击两个按钮,您将看到 **Hello World** 文本的字体会更改,这是因为针对每个点击事件都调用了已注册的点击事件处理程序方法。

练习

我建议尝试为不同的事件类型编写不同的事件处理程序,并了解不同事件类型及其处理的精确区别。与菜单、微调器、选择器小部件相关的事件略有不同,但它们也基于上述相同的概念。

广告
© . All rights reserved.