安卓學習筆記之事件分發機制
觸摸事件的分發機制
安卓的UI界面是一種樹形壯結構的。層層嵌套組件,既然是很多組件嵌套在一起,倘若組件之間層層疊加,都有各自的觸摸事件,當我們點擊的時候,就不知道是哪個組件做出的響應。所以有了事件的分發機制。
主要有三個方法:
dispatchTouchEvent()
onTouchEvent()
onInterceptEvent()
用代碼來實際演示各自代表什么意思。
圖片來自http://www.jianshu.com/p/38015afcdb58
Demo
我自定義了一個ViewGroup繼承自FrameLayout,里面包含這ChildView這個子空間,最外面則是Activity。
為了避免重復的代碼,我寫了一個工具類。
public class TouchUtil {
public static void logTouch(MotionEvent event, String name) {
int action = event.getAction();
switch (action){
case MotionEvent.ACTION_DOWN:
Log.i("does",name+"ACTION_DOWN 響應");
break;
case MotionEvent.ACTION_UP:
Log.i("does",name+"ACTION_UP 響應");
break;
case MotionEvent.ACTION_MOVE:
Log.i("does",name+"ACTION_MOVE 響應");
break;
}
}
}
ParentView
public class ParentViewGroup extends FrameLayout {
public ParentViewGroup(@NonNull Context context) {
super(context);
}
public ParentViewGroup(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
TouchUtil.logTouch(event,"ParentView onTouchEvent -------");
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
TouchUtil.logTouch(ev,"Dispatch ParentView ---------");
// return super.dispatchTouchEvent(ev);
return super.dispatchTouchEvent(ev);
}
}
ChildView
public class ChildView extends View {
public ChildView(Context context) {
super(context);
}
public ChildView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
TouchUtil.logTouch(event,"ChildView onTouchEvent -------");
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
TouchUtil.logTouch(ev,"Dispatch childView---------");
return super.dispatchTouchEvent(ev);
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
TouchUtil.logTouch(event,"MainActivity onTouchEvent -------");
return super.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
TouchUtil.logTouch(ev,"Dispatch Activity --------");
return super.dispatchTouchEvent(ev);
}
}
布局文件
<?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:background="#f00"
tools:context="com.example.touch.MainActivity">
<com.example.touch.ParentViewGroup
android:layout_width="300dp"
android:layout_centerInParent="true"
android:layout_height="300dp"
android:background="#0f0"
>
<com.example.touch.ChildView
android:layout_gravity="center"
android:background="#00f"
android:layout_width="150dp"
android:layout_height="150dp" />
</com.example.touch.ParentViewGroup>
</RelativeLayout>
當我們運行程序的時候會,當我們點擊ChildView的時候,輸出日志信息,
08-25 05:34:28.599 31190-31190/com.example.touch I/does: Dispatch Activity ——–ACTION_DOWN 響應
08-25 05:34:28.600 31190-31190/com.example.touch I/does: Dispatch ParentView ———ACTION_DOWN 響應
08-25 05:34:28.600 31190-31190/com.example.touch I/does: Dispatch childView———ACTION_DOWN 響應
08-25 05:34:28.600 31190-31190/com.example.touch I/does: ChildView onTouchEvent ——-ACTION_DOWN 響應
08-25 05:34:28.600 31190-31190/com.example.touch I/does: ParentView onTouchEvent ——-ACTION_DOWN 響應
08-25 05:34:28.600 31190-31190/com.example.touch I/does: MainActivity onTouchEvent ——-ACTION_DOWN 響應
08-25 05:34:28.695 31190-31190/com.example.touch I/does: Dispatch Activity ——–ACTION_UP 響應
08-25 05:34:28.695 31190-31190/com.example.touch I/does: MainActivity onTouchEvent ——-ACTION_UP 響應
從上面Log日志當中我們可以知道。
dispatchEvent表示的是事件的一個分發機制方法,表示從外向里分發事件。默認返回為false,所以先執行dispatch事件。
當事件分發結束之后,處理TouchEvent事件,觸摸事件則向上傳遞。默認返回的值為false。
onInterceptTouchEvent
這個函數代表的是攔截事件,顧名思義,默認返回的就是false,如果返回為true說明在當前view上進行攔截觸摸事件。比如我在ParentView重寫onInterceptTouchEvent方法并返回為true,則表示事件不再往下傳遞,通俗來說就是沒ChildView什么事情了。但是這需要注意的是,只有viewGroup才有!!
這三個方法,用一個表格來說明
圖片來自http://www.jianshu.com/p/38015afcdb58
智能推薦
Android View事件分發機制學習筆記
前言 我們都知道: 一個按鈕在點擊的時候有三種情況DOWN,MOVE,UP,即按下,按住,抬起三種情況,屬于OnTouch事件。 有的時候也有兩種情況的時候LongClick,Click,即長按與點擊,屬于OnTouchEven事件。 你或許會感到奇怪按鈕只能注冊OnTouch,OnClickListener,OnLongClickListener并無法注冊OnTouchEven事件,為什么能說兩...
Android事件分發機制學習筆記
一.事件傳遞在那些類中: 1.Activity中:dispathTouchEvent,onToutchEvent 2.ViewGroup:dispathTouchEvent,onInterceptTouchEvent,onTouchEvent 3.View:dispathTouchEvent,onTouchEvent 二.傳遞過程: 1.觸摸手機進入事件分發Activity的dispathTouc...
安卓學習筆記13:安卓觸摸事件
文章目錄 零、學習目標 一、安卓觸摸事件 1、觸摸分類 2、觸摸動作 3、觸摸監聽器 4、觸摸方法 5、觸點個數與坐標 二、安卓單點觸摸 三、教學案例——通過觸摸移動米老鼠 (一)運行效果 (二)涉及知識點 (三)實現步驟 1、創建安卓應用【MoveMickeyByTouch】 2、準備背景圖片與米老鼠圖片,拷貝到drawable目錄里 3、布局資源文件activity_m...
安卓學習筆記12:安卓按鍵事件
文章目錄 零、學習目標 一、安卓界面事件 (一)安卓常用事件 1、單擊事件 2、焦點事件 3、按鍵事件 4、觸碰事件 (二)安卓事件處理方式 1、基于回調的事件處理機制 2、基于監聽的事件處理機制 二、教學案例——通過按鍵移動米老鼠 (一)運行效果 (二)涉及知識點 (三)實現步驟 1、創建安卓應用【MoveMickeyByKey】 2、準備背景圖片與米老鼠圖片,拷貝到dr...
JavaScript學習筆記(三)之事件處理機制
七、捕獲事件 (一)事件 以上為基本事件,事件處理程序的名稱只是在事件名稱前面加上一個前綴‘on’。 (二)0級事件處理 內聯模式即以屬性的形式為HTML元素添加屬性的方法 傳統模式即通過對象屬性將一個函數指定為事件處理程序。如果想禁用事件處理,可以將事件處理程序的值附為NULL。 注:在DOM Level 0 事件模型中,任何對象只允許指定一個事件處理程序,因此指定的函數...
猜你喜歡
安卓自定義View進階-事件分發機制原理
前講解了很多與View繪圖相關的知識,你可以在 安卓自定義View教程目錄 中查看到這些文章,如果你理解了這些文章,那么至少2D繪圖部分不是難題了,大部分的需求都能滿足,但是關于View還有很多知識點,例如: 讓繪圖更加炫酷的Paint,讓View動起來的動畫,與用戶交互的觸控事件 等一系列內容。本次就帶大家簡單的了解一下與交互息息相關的東西-事件分發原理。...
安卓自定義View進階-事件分發機制詳解
Android 事件分發機制詳解,在上一篇文章 事件分發機制原理 中簡要分析了一下事件分發機制的原理,原理是十分簡單的,一句話就能總結:責任鏈模式,事件層層傳遞,直到被消費。 雖然原理簡單,但是隨著 Android 不斷的發展,實際運用場景也越來越復雜,所以想要徹底玩轉事件分發機制還需要一定技巧,本篇事件分發機制詳解將帶大家了解 … 你以為我接下來要講源碼? 我就不按套路,所有的源碼...
安卓自定義View進階-事件分發機制原理
之前講解了很多與View繪圖相關的知識,你可以在 安卓自定義View教程目錄 中查看到這些文章,如果你理解了這些文章,那么至少2D繪圖部分不是難題了,大部分的需求都能滿足,但是關于View還有很多知識點,例如: 讓繪圖更加炫酷的Paint,讓View動起來的動畫,與用戶交互的觸控事件 等一系列內容。本次就帶大家簡單的了解一下與交互息息相關的東西-事件分發原理。 本次魔法小火車的終點站是事件分發,請...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...