成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Andriod從源碼的角度詳解View,ViewGroup的Touch事件的分發(fā)機(jī)制

今天這篇文章主要分析的是Android的事件分發(fā)機(jī)制,采用例子加源碼的方式讓大家深刻的理解Android事件分發(fā)的具體情況,雖然網(wǎng)上很多Android的事件分發(fā)的文章,有些還寫的不錯(cuò),但是我還是決定寫這篇文章,用我自己的思維方式來幫助大家理解Android事件分發(fā),Android事件分發(fā)到底有多重要呢?相信很多Android開發(fā)者都明白吧,這個(gè)我就不介紹了,我也寫了很多篇文章里面涉及到Android的事件處理的問題,可能不理解Android事件分發(fā)的朋友會(huì)有點(diǎn)難理解吧,不過沒關(guān)系,相信看了這篇文章的你會(huì)對Android事件分發(fā)有進(jìn)一步的理解。我這篇文章分析的源碼是Android 2.2的源碼, 也許你會(huì)說,干嘛不去分析最新的源碼呢?我這里要解釋一下,Android 2.2的源碼跟最新的源碼在功能效果方面是一樣的,只不過最新的源碼相對于Android 2.2來說更加健壯一些, Android 2.2的事件處理的代碼幾乎都寫在一個(gè)方法體里面,而最新的源碼分了很多個(gè)方法寫,如果用最新的源碼調(diào)用方法會(huì)繞來繞去的,相信你看的也會(huì)暈,出于這個(gè)考慮,我就拿Android 2.2的源碼來給大家分析。

我們提供的服務(wù)有:成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、高縣ssl等。為成百上千企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的高縣網(wǎng)站制作公司

ViewGroup的事件分發(fā)機(jī)制

我們用手指去觸摸Android手機(jī)屏幕,就會(huì)產(chǎn)生一個(gè)觸摸事件,但是這個(gè)觸摸事件在底層是怎么分發(fā)的呢?這個(gè)我還真不知道,這里涉及到操作硬件(手機(jī)屏幕)方面的知識(shí),也就是Linux內(nèi)核方面的知識(shí),我也沒有了解過這方面的東西,所以我們可能就往上層來分析分析,我們知道Android中負(fù)責(zé)與用戶交互,與用戶操作緊密相關(guān)的四大組件之一是Activity, 所以我們有理由相信Activity中存在分發(fā)事件的方法,這個(gè)方法就是dispatchTouchEvent(),我們先看其源碼吧

public boolean dispatchTouchEvent(MotionEvent ev) {
                                                                                                                          
        //如果是按下狀態(tài)就調(diào)用onUserInteraction()方法,onUserInteraction()方法
        //是個(gè)空的方法, 我們直接跳過這里看下面的實(shí)現(xiàn)
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction();
        }
                                                                                                                                  
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
                                                                                                                                  
        //getWindow().superDispatchTouchEvent(ev)返回false,這個(gè)事件就交給Activity
        //來處理, Activity的onTouchEvent()方法直接返回了false
        return onTouchEvent(ev);
    }

這個(gè)方法中我們還是比較關(guān)心getWindow()的superDispatchTouchEvent()方法,getWindow()返回當(dāng)前Activity的頂層窗口Window對象,我們直接看Window API的superDispatchTouchEvent()方法

/**
     * Used by custom windows, such as Dialog, to pass the touch screen event
     * further down the view hierarchy. Application developers should
     * not need to implement or call this.
     *
     */
    public abstract boolean superDispatchTouchEvent(MotionEvent event);

這個(gè)是個(gè)抽象方法,所以我們直接找到其子類來看看superDispatchTouchEvent()方法的具體邏輯實(shí)現(xiàn),Window的唯一子類是PhoneWindow,我們就看看PhoneWindow的superDispattEvent()

public boolean superDispatchTouchEvent(KeyEvent event) {
        return mDecor.superDispatchTouchEvent(event);
    }

里面直接調(diào)用DecorView類的superDispatchTouchEvent方法,或許很多人不了解DecorView這個(gè)類,DecorView是PhoneWindow的一個(gè)final的內(nèi)部類并且繼承FrameLayout的,也是Window界面的最頂層的View對象,這是什么意思呢?別著急,我們接著往下看

我們先新建一個(gè)項(xiàng)目,取名AndroidTouchEvent,然后直接用模擬器運(yùn)行項(xiàng)目, MainActivity的布局文件為

<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"
    tools:context=".MainActivity" >
                                                                                                             
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/hello_world" />
                                                                                                             
</RelativeLayout>

利用hierarchyviewer工具來查看下MainActivity的View的層次結(jié)構(gòu),如下圖

Andriod 從源碼的角度詳解View,ViewGroup的Touch事件的分發(fā)機(jī)制

好了,就分析到這里吧,差不多分析完了,還有一種情況沒有分析到,例如我將CustomLayout的代碼改成下面的情形,Touch事件又是怎么分發(fā)的呢?我這里就不帶大家分析了

package com.example.androidtouchevent;
                                            
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.RelativeLayout;
                                            
public class CustomLayout extends RelativeLayout {
                                                
    public CustomLayout(Context context, AttributeSet attrs) {
        super(context, attrs, 0);
    }
                                            
    public CustomLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
                                            
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }
                                            
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if(ev.getAction() == MotionEvent.ACTION_MOVE){
            return true;
        }
        return super.onInterceptTouchEvent(ev);
    }
                                                
                                            
}

這篇文章的篇幅有點(diǎn)長,如果你想了解Touch事件的分發(fā)機(jī)制,你一定要認(rèn)真看完,下面來總結(jié)一下吧

1.Activity的最頂層Window是PhoneWindow,PhoneWindow的最頂層View是DecorView

2.一個(gè)clickable或者longClickable的View會(huì)永遠(yuǎn)消費(fèi)Touch事件,不管他是enabled還是disabled的

3.View的長按事件是在ACTION_DOWN中執(zhí)行,要想執(zhí)行長按事件該View必須是longClickable的,并且不能產(chǎn)生ACTION_MOVE

4.View的點(diǎn)擊事件是在ACTION_UP中執(zhí)行,想要執(zhí)行點(diǎn)擊事件的前提是消費(fèi)了ACTION_DOWN和ACTION_MOVE,并且沒有設(shè)置OnLongClickListener的情況下,如設(shè)置了OnLongClickListener的情況,則必須使onLongClick()返回false

5.如果View設(shè)置了onTouchListener了,并且onTouch()方法返回true,則不執(zhí)行View的onTouchEvent()方法,也表示View消費(fèi)了Touch事件,返回false則繼續(xù)執(zhí)行onTouchEvent()

6.Touch事件是從最頂層的View一直分發(fā)到手指touch的最里層的View,如果最里層View消費(fèi)了ACTION_DOWN事件(設(shè)置onTouchListener,并且onTouch()返回true 或者onTouchEvent()方法返回true)才會(huì)觸發(fā)ACTION_MOVE,ACTION_UP的發(fā)生,如果某個(gè)ViewGroup攔截了Touch事件,則Touch事件交給ViewGroup處理

7.Touch事件的分發(fā)過程中,如果消費(fèi)了ACTION_DOWN,而在分發(fā)ACTION_MOVE的時(shí)候,某個(gè)ViewGroup攔截了Touch事件,就像上面那個(gè)自定義CustomLayout,則會(huì)將ACTION_CANCEL分發(fā)給該ViewGroup下面的Touch到的View,然后將Touch事件交給ViewGroup處理,并返回true

當(dāng)前名稱:Andriod從源碼的角度詳解View,ViewGroup的Touch事件的分發(fā)機(jī)制
文章分享:http://jinyejixie.com/article22/pgsdcc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、網(wǎng)站設(shè)計(jì)公司網(wǎng)站維護(hù)、用戶體驗(yàn)、電子商務(wù)、搜索引擎優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計(jì)
虞城县| 体育| 台东市| 刚察县| 阜城县| 乳源| 都匀市| 册亨县| 潢川县| 体育| 马龙县| 高青县| 望谟县| 寻乌县| 外汇| 德化县| 乐至县| 肃宁县| 田阳县| 红河县| 平谷区| 虹口区| 奉贤区| 浙江省| 慈溪市| 通州市| 阿拉善左旗| 莲花县| 松溪县| 齐齐哈尔市| 绥德县| 平塘县| 章丘市| 新泰市| 茶陵县| 兴隆县| 玛纳斯县| 长子县| 宣汉县| 余姚市| 错那县|