Android事件處理


事件是一種有用來收集使用者與應用程式互動資料的互動元件,如按鍵或觸控屏等放置事件,因為每個事件從Android框架維護事件佇列先入先出(FIFO)基礎上的佇列。可以在程式中捕獲這些事件,按要求並採取適當的動作。

有以下三個概念涉及到Android事件管理:

  • 事件監聽器: 主要涉及建立一個Android的GUI檢視類,View類提供了一些事件監聽器。事件監聽器是物件接收通知在事件發生時。

  • 事件監聽器註冊: 事件註冊事件處理程式被註冊了事件偵聽器的過程,使該處理呼叫的事件偵聽器觸發事件。

  • 事件處理程式: 當一個事件發生時,已註冊的事件和事件監聽器,事件監聽器呼叫事件處理程式,這是實際處理事件的方法。

事件偵聽器和事件處理程式

事件處理程式 事件監聽器說明
onClick() OnClickListener()
當使用者點選任意或觸控或焦點事件像按鈕,文字,圖片等,將使用onClick()事件處理程式來處理任何部件的事件
onLongClick() OnLongClickListener()
當使用者點選或觸控或焦點事件像按鈕,文字,影象等,為1秒以上的任何外掛時被呼叫。使用onLongClick()事件處理程式來處理這樣的事件
onFocusChange() OnFocusChangeListener()
當控制元件失去焦點時被呼叫。使用者進入離開檢視專案。使用onFocusChange()事件處理程式來處理這樣的事件
onKey() OnFocusChangeListener()
當使用者焦點並按下或釋放裝置上的硬體鍵時被呼叫。將使用onKey()事件處理程式來處理這樣的事件
onTouch() OnTouchListener()
當使用者按下該鍵時及釋放鍵,或在螢幕上的任何移動手勢時被呼叫。使用onTouch()事件處理程式來處理這樣的事件
onMenuItemClick() OnMenuItemClickListener()
當使用者選擇一個選單項時被呼叫。使用onMenuItemClick()事件處理程式來處理這樣的事件

還有更多可用作為View類如:OnHoverListener,OnDragListener 等,應用程式可能需要一部分的事件偵聽器。因此,建議參考官方Android應用程式開發文件,開發一個複雜的應用程式。

註冊事件監聽器:

事件註冊事件處理程式被註冊事件偵聽器的過程,使處理時呼叫事件偵聽器處理事件。雖然有一些方法註冊可以任何事件的事件偵聽器,但要列出只前3種方式,可以根據實際情況使用。

  • 使用匿名內部類

  • Activity 活動類實現Listener介面

  • 使用布局檔案 activity_main.xml 直接指定事件處理程式(方法)

下面將提供三種情景的詳細的例子:

事件處理舉例

使用匿名內部類的事件監聽器註冊

在這裡,將建立一個匿名的執行監聽,如果每個類只有一個單控制器,將引數傳遞給事件處理程式。在這種方法中的事件處理方法可以存取私有資料的活動。沒有提及需要呼叫到活動。

但是,如果宣告一個以上處理程式的控制器,剪下和貼上程式碼的處理程式和處理程式的程式碼很長,程式碼更難維護。

以下是簡單的步驟來展示我們將如何利用獨立的 Listener類 註冊並捕獲點選(click)事件。類似的方式,可以實現所需的任何其他事件型別的偵聽。

步驟 描述
1 使用Android Studio建立一個Android應用程式專案,將其命名為:EventDemo
2 修改 src/MainActivity.java 程式檔案,以新增 click事件偵聽器並處理程式定義的兩個按鈕
3 修改 res/layout/activity_main.xml 檔案的預設內容包括Android的UI控制元件
4 定義res/values/strings.xml 檔案所需的常數
5 執行該應用程式啟動Android模擬器並驗證應用程式所做的修改結果

以下是主 activity 檔案src/com.yiibai.eventdemo/MainActivity.java 的內容。這個檔案可以包括每個生命週期的根本方法。

package com.yiibai.eventdemo;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //--- find both the buttons---
        Button sButton = (Button) findViewById(R.id.button_s);
        Button lButton = (Button) findViewById(R.id.button_l);
        
        // -- register click event with first button ---
        sButton.setOnClickListener(new View.OnClickListener() {
           public void onClick(View v) {
               // --- find the text view --
               TextView txtView = (TextView) findViewById(R.id.text_id);
               // -- change text size --
               txtView.setTextSize(14);
           }
        });
        
        // -- register click event with second button ---
        lButton.setOnClickListener(new View.OnClickListener() {
           public void onClick(View v) {
               // --- find the text view --
               TextView txtView = (TextView) findViewById(R.id.text_id);
               // -- change text size --
               txtView.setTextSize(24);
           }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
}

下面是 res/layout/activity_main.xml 檔案的內容:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical" >


    <Button 
    android:id="@+id/button_s"
    android:layout_height="wrap_content" 
    android:layout_width="match_parent" 
    android:text="@string/button_small"/>
    
    <Button 
    android:id="@+id/button_l"
    android:layout_height="wrap_content" 
    android:layout_width="match_parent" 
    android:text="@string/button_large"/>

    <TextView
    android:id="@+id/text_id"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:capitalize="characters"
    android:text="@string/hello_world" />

</LinearLayout>

以下檔案 res/values/strings.xml 定義了兩個新的常數:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">EventDemo - tw511.com</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
   <string name="button_small">小號字型</string>
   <string name="button_large">大號字型</string>
   
</resources>

以下是 AndroidManifest.xml 檔案的預設內容:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yiibai.guidemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.yiibai.guidemo.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>

我們嘗試執行EventDemo 應用程式。AVD安裝的應用程式,並啟動它,如果一切設定和應用都沒有問題,它會顯示以下模擬器視窗:

Android事件處理

現在嘗試一下,會看到兩個按鈕逐一的Hello World文字,字型會發生變化,對每次點選事件發生,因為註冊的click事件處理方法被呼叫。

以上程式碼下載:http://pan.baidu.com/s/1hqrIjx6
 

註冊使用活動實現監聽器介面

在這裡,activity類實現Listener介面方法處理主活動,然後呼叫setOnClickListener(this)程式。

如果應用程式只有一個單一的控制元件這種方法是很好的,但需要做進一步的程式設計檢查控制生成的事件(監聽器型別)。第二不能將引數傳遞到監聽器,多個控制元件時不能起作用。

下面是簡單的步驟來展示如何實現Listener類註冊並捕獲click事件。類似的方式,可以實現所需的任何其他事件型別的監聽。

步驟 描述
1 我們需要建立一個Android應用程式 :EventDemo2
2 修改 src/MainActivity.java 檔案的內容,以新增click事件偵聽器和處理程式定義的兩個按鈕
3 上一個例子中的 res/layout/activity_main.xml 檔案不用做任何改變,它仍將如上圖所示。
4 上一個例子中的 res/values/strings.xml 檔案不做任何變化,如上圖所示。
5 執行該應用程式啟動Android模擬器並驗證應用程式所做的修改結果。

以下是主活動活動檔案 src/com.yiibai.eventdemo2/MainActivity.java 的內容。這個檔案可以包括每個生命週期基礎方法。

package com.example.eventdemo;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //--- find both the buttons---
        Button sButton = (Button) findViewById(R.id.button_s);
        Button lButton = (Button) findViewById(R.id.button_l);
        
        
        // -- register click event with first button ---
        sButton.setOnClickListener(this);
        // -- register click event with second button ---
        lButton.setOnClickListener(this);
    }
        
    //--- Implement the OnClickListener callback
    public void onClick(View v) {
       if(v.getId() == R.id.button_s)
       { 
            // --- find the text view --
            TextView txtView = (TextView) findViewById(R.id.text_id);
            // -- change text size --
            txtView.setTextSize(14);
            return;
       }
       if(v.getId() == R.id.button_l)
       { 
            // --- find the text view --
            TextView txtView = (TextView) findViewById(R.id.text_id);
            // -- change text size --
            txtView.setTextSize(24);
            return;
       }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
}

我們嘗試執行EventDemo2 應用程式。AVD安裝的應用程式,並啟動它,如果一切設定和應用都沒有問題,它會顯示以下模擬器視窗:

現在嘗試一下,會看到兩個按鈕被點選後 "Hello World" 文字字型會發生變化,對每次點選事件,註冊的 click 事件處理方法被呼叫。

上面例子程式程式碼下載地址:http://pan.baidu.com/s/1i3pEvpr
 

使用布局檔案ACTIVITY_MAIN.XML註冊

在這裡事件處理程式Activity類沒有實現監聽器介面,也沒有註冊任何偵聽器方法。相反使用布局檔案(activity_main.xml),通過android:onClick屬性指定的處理程式方法click事件。可以控制??不同的點選事件不同的控制,通過不同的事件處理方法。 

事件處理程式方法必須有一個返回型別為void,並作為一個引數來檢視。方法名稱可以是任意的,主類不需要實現任何特定的介面。

這種方法不會允許將引數傳遞給監聽器,Android開發人員將很難知道哪種方法處理程式控制,需要到activity_main.xml檔案檢視才能知道。其次,不能處理除click事件外的任何其他事件。

以下是簡單的步驟來展示如何能利用布局main.xml檔案註冊並捕獲click事件。

步驟 描述
1 建立一個Android應用程式專案:EventDemo3.
2 修改src/MainActivity.java檔案,以新增定義兩個按鈕的click事件偵聽器和處理程式
3 修改布局檔案 res/layout/activity_main.xml,指定這兩個按鈕的事件處理程式
4 檔案 res/values/strings.xml 不用做修改,使用上面的例子中的內容就可以
5 執行該應用程式啟動Android模擬器並驗證應用程式所做的修改結果。

以下是修改主活動檔案src/com.yiibai.eventdemo/MainActivity.java的內容。這個檔案可以包括每個生命週期的基本方法。

package com.example.eventdemo;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
        
    //--- Implement the event handler for the first button.
    public void doSmall(View v)  {
       // --- find the text view --
       TextView txtView = (TextView) findViewById(R.id.text_id);
       // -- change text size --
       txtView.setTextSize(14);
       return;
   }
   //--- Implement the event handler for the second button.
   public void doLarge(View v)  {
       // --- find the text view --
       TextView txtView = (TextView) findViewById(R.id.text_id);
       // -- change text size --
       txtView.setTextSize(24);
       return;
   }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
}

將以下的 res/layout/activity_main.xml 檔案的內容。在這裡,我們必須給這兩個按鈕新增 android:onClick="methodName" ,這將註冊給定的方法名,以新增單擊事件處理程式。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical" >


    <Button 
    android:id="@+id/button_s"
    android:layout_height="wrap_content" 
    android:layout_width="match_parent" 
    android:text="@string/button_small"
    android:onClick="doSmall"/>
    
    <Button 
    android:id="@+id/button_l"
    android:layout_height="wrap_content" 
    android:layout_width="match_parent" 
    android:text="@string/button_large"
    android:onClick="doLarge"/>

    <TextView
    android:id="@+id/text_id"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:capitalize="characters"
    android:text="@string/hello_world" />

</LinearLayout>

我們嘗試執行EventDemo3 應用程式。AVD上安裝的應用程式,並啟動它,如果一切設定和應用都沒有問題,它會顯示以下模擬器視窗:

現在嘗試一下,會看到兩個按鈕的 Hello World文字的字型會發生變化,對每次點選事件,註冊的click事件處理方法被呼叫。

以上程式碼下載地下:http://pan.baidu.com/s/1nthyBDR