Android的事件處理機制詳解(一)—–基於監聽的事件處理機制

基於監聽的事件處理機制

前言:

我們開發的app更多的時候是需要與用戶的交互—-即對用戶的操作進行響應

這就涉及到瞭android的事件處理機制;

android給我們提供瞭兩套功能強大的處理機制:

①基於監聽的事件處理機制

②基於回調的事件處理機制

在這一節中,我們會先介紹一下基於監聽的事件處理機制

好瞭,廢話不多說!

我們要先瞭解一下監聽處理機制的模型

監聽的處理模型:

處理模型圖:

文字表述:

事件監聽機制中由事件源,事件,事件監聽器vc3Ryb25nPsj9wOC21M/z1+mzyTwvcD4KPHA+tKbA7cH3s8w6PC9wPgo8cD48c3Ryb25nPnN0ZXAgMTo8L3N0cm9uZz7OqsSzuPbKwrz+1LQo1+m8/inJ6NbD0ru49rzgzP3G9yzTw9PavODM/dPDu6ey2df3PC9wPgo8cD48c3Ryb25nPnN0ZXAgMjo8L3N0cm9uZz7Tw7untcSy2df3LLSlt6LBy8rCvP7UtLXEvODM/cb3PC9wPgo8cD48c3Ryb25nPnN0ZXAgMzo8L3N0cm9uZz7J+rPJwcu21NOmtcTKwrz+ttTP8zwvcD4KPHA+PHN0cm9uZz5zdGVwIDQ6PC9zdHJvbmc+vavV4rj2ysK8/tS0ttTP89f3zqqyzsr9tKu4+MrCvP684Mz9xvc8L3A+CjxwPjxzdHJvbmc+c3RlcCA1Ojwvc3Ryb25nPsrCvP684Mz9xve21MrCvP621M/zvfjQ0MXQts8s1rTQ0LbU06a1xMrCvP60psDtxvcottTTpsrCvP61xLSmwO23vbeoKTwvcD4KPHA+PGJyPgo8L3A+CjxoMz656cTJOjwvaDM+CjxwPsrCvP684Mz9u/rWxsrH0rvW1s6vxcnKvbXEysK8/rSmwO27+tbGLMrCvP7UtCjX6bz+KcrCvP60psDtzq/N0Lj4ysK8/rzgzP3G9zwvcD4KPHA+tbHKwrz+1LS3osn61sa2qMrCvP7KsSy+zc2o1qrKwrz+vODM/cb3LNa00NDP4NOmtcSy2df3PC9wPgo8cD48YnI+CjwvcD4KPHA+PGJyPgo8L3A+CjxoMz7KudPD0M7KvTo8L2gzPgo8cD48YnI+CjwvcD4KPHA+PC9wPgo8cD7KtcD9OjwvcD4KPHA+1eLA78q1z9a1xMrHteO797C0xaW68yzP1Mq+dG9hc3TQxc+izOHKvjwvcD4KPHA+zqrBy9Hdyr4s0tTPwsrH08Oyu82stcTQzsq9yrXP1sjnzby1xNCnufssv8nX0M+4tKfEprT6wus8L3A+CjxwPjxicj4KPC9wPgo8cD7Qp7n7zbw6PC9wPgo8aW1nIHNyYz0=”/wp-content/images1/20181210/201403220827217939.jpg” alt=”\”>

①直接使用匿名內部類,作為事件監聽器

ps:就是我們平時最常用的那種,setXxxListener後就重寫裡面的對應方法

通常都是臨時使用一次,復用性不高

代碼:

xml就是一個普通的按鈕,這就不給出瞭

MainActivity.java

package com.jay.example.innerlisten;

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


public class MainActivity extends Activity {

	private Button btnshow;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        btnshow = (Button) findViewById(R.id.btnshow);
        btnshow.setOnClickListener(new OnClickListener() {
			//重寫點擊事件的處理方法onClick()
			@Override
			public void onClick(View v) {
				//顯示Toast信息
				Toast.makeText(getApplicationContext(), "你點擊瞭按鈕", Toast.LENGTH_SHORT).show();
			}
		});
    }    
}

②使用內部類作為事件監聽器

這裡和上面的匿名內部類不一樣的哦

使用優點:可以在該類中復用,可直接訪問外部類的所有界面組件

代碼:

package com.jay.example.innerlisten;

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


public class MainActivity extends Activity {

	private Button btnshow;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        btnshow = (Button) findViewById(R.id.btnshow);
        //直接new一個內部類對象作為參數
        btnshow.setOnClickListener(new BtnClickListener());
        
    } 
    
    
    //定義一個內部類,實現View.OnClickListener接口,並重寫onClick()方法
    class BtnClickListener implements View.OnClickListener
    {
		@Override
		public void onClick(View v) {
			
			Toast.makeText(getApplicationContext(), "按鈕被點擊瞭", Toast.LENGTH_SHORT).show();
		}
    	
    }
}

③使用外部類作為事件監聽器

就是另外創建一個處理事件的Java文件,該形式比較少見

因為外部類不能直接訪問用戶界面類中的組件,要通過構造方法將組件傳入使用,

這樣的結果就是代碼不夠簡潔

ps:為瞭演示,這裡通過textView代替Toast顯示!

效果圖:

代碼:

佈局比較簡單,就是一個按鈕+文本框,這裡不給出瞭

另外編寫一個外部類:

MyClick.java

package com.jay.example.innerlisten;

import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class MyClick implements OnClickListener {

	private TextView textshow;
	//把文本框作為參數傳入
	public MyClick(TextView txt)
	{
		textshow = txt;
	}
	
	@Override
	public void onClick(View v) {
		//點擊後設置文本框顯示的文字
		textshow.setText("點擊瞭按鈕!");
	}

}

MainActivity.java

package com.jay.example.innerlisten;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.app.Activity;


public class MainActivity extends Activity {

	private Button btnshow;
	private TextView txtshow;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        btnshow = (Button) findViewById(R.id.btnshow);
        txtshow = (TextView) findViewById(R.id.textshow);
        //直接new一個外部類,並把TextView作為參數傳入
        btnshow.setOnClickListener(new MyClick(txtshow));
        
    }     
}

④直接使用Activity作為事件監聽器

隻需要讓Activity類實現~Listener事件監聽接口,在Activity中定義重寫對應的事件處理器方法

eg:Activity實現瞭OnclickListener接口,重寫onClick(view)方法

當為某組件添加該事件監聽器對象時,可以直接setXxxListener(this)即可

效果圖:

佈局文件略

MainActivity.java

package com.jay.example.innerlisten;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import android.app.Activity;

//讓Activity方法實現OnClickListener接口
public class MainActivity extends Activity implements OnClickListener{

	private Button btnshow;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        btnshow = (Button) findViewById(R.id.btnshow);
        //直接寫個this
        btnshow.setOnClickListener(this);
        
    }

    //重寫接口中的抽象方法
	@Override
	public void onClick(View v) {
		Toast.makeText(getApplicationContext(), "點擊瞭按鈕", Toast.LENGTH_SHORT).show();		
	}     
}

重要的OnTouchEvent事件解析

之所以在這裡講解下OnTouchEvent事件,並不是單單因為他是事件監聽機制的一個例子

而且因為他的調用流程比較特別,同時因為這個事件是我們實際開發中使用得比較多的

所有的view組件都重寫瞭該方法,應用程序可以通過該方法處理手機屏幕的觸摸事件。

方法聲明:

public boolean onTouchEvent(MotionEvent event);

使用流程:

①為某個view(組件)setOnTouchListener(new OnTouchListener())

②重寫onTouch()方法

③因為有三種比較常用的觸摸狀態:

MotionEvent.ACTION_DOWN:按下

MotionEvent.ACTION_MOVE:移動

MotionEvent.ACTION_UP:放開

所以我們通常是通過switch進行分類處理的,switch(event.getAction ),然後每個case ~:處理對應事件

方法調用順序解析:

由方法聲明我們知道onTouchEvent返回的是一個boolean值,要麼true,要麼false

而這兩個的不同之處就是,調用完onTouch()中的方法後是否再調用外部的方法

這裡舉個簡單的例子:

我們為某個按鈕設置瞭onTouch(),onClick(),onLongClick()三個方法;那麼他們的調用順序是怎麼樣的呢?

答:有以下兩種情況:

①返回true:按下時調用ACTION_DOWN的方法,調用完後調用ACTION_MOVE方法,隻要手指一直按著系統就會不斷地響應這個

方法,原因是(android對觸摸事件比較敏感,雖然我們的手指感覺是靜止不動的,其實手指卻在不停地微顫抖震動);當我們的手指離開

瞭屏幕,這個時候調用 MotionEvent.ACTION_UP方法,接著這個流程就完瞭

②返回false:和上面那個流程一樣,但是離開屏幕後就會調用另外的2個方法瞭:

如果你是短按的話,那麼會調用onClick()方法

如果你是長按得話,那麼會調用onLongClick()方法;

然後才玩完

上面的這兩種情況並不難理解

讀者可以自己寫代碼驗證一下,然後通過log.i()查看調用的順序信息

最後給大傢演示一下

調用OnTouchEvent() onMove方法的使用吧

MoveTo()方法使用實例:

這個用的比較多,例子還是舊的,在幀佈局那一節就給出來瞭

這裡簡單地介紹下用法吧:

我們隻需要通過參數event就可以獲得當前點擊的位置瞭

x = event.getX(); //獲得點擊的X坐標

y = event.getY(); //獲得點擊的Y坐標

詳細的見代碼吧:

MoveTo方法使用實例

原文:

點擊打開鏈接

那個隨手指移動的萌妹子就是瞭!

總結:

好吧,這一節的基於監聽的事件處理機制就總結到這裡吧

如果有什麼遺漏的,或者錯誤,或者有其他意見的

歡迎指出,O(∩_∩)O謝謝

發佈留言