觸摸事件之onTouch和onTouchEvent

近日連續(xù)看了兩篇講觸摸事件的,心里不禁產(chǎn)生了一個(gè)疑問坛吁,故這篇文章也是因?yàn)檫@個(gè)疑問而寫的盏筐。這個(gè)疑問就是:“為什么會(huì)View類里面會(huì)同時(shí)有onTouch和onTouchEvent兩個(gè)觸摸相關(guān)的方法?”如果你心里已經(jīng)有答案了,這篇文章可跳過洒沦,如果有跟我一樣懵逼的,不妨你們也仔細(xì)回憶下到底為什么价淌?

有了這個(gè)疑問在申眼,我們的目的性就很明確了。還是先來看看它們?cè)诖a中的具體用法吧蝉衣。

//...
            ListenerInfo li = mListenerInfo;
            if (li != null && li.mOnTouchListener != null
                    && (mViewFlags & ENABLED_MASK) == ENABLED
                    && li.mOnTouchListener.onTouch(this, event)) {
                result = true;
            }

            if (!result && onTouchEvent(event)) {
                result = true;
            }
//...

系統(tǒng)先進(jìn)行mOnTouchListener及onTouch返回值等相關(guān)條件的判斷括尸,不滿足的話再執(zhí)行onTouchEvent。病毡,兩個(gè)都是觸摸相關(guān)的濒翻,不同的是onTouch方法比onTouchEvent方法多接收了一個(gè)參數(shù)。這又是為何啦膜?

我們繼續(xù)看系統(tǒng)關(guān)于onTouch方法的說明:

/**
 * Interface definition for a callback to be invoked when a touch event is
 * dispatched to this view. The callback will be invoked before the touch
 * event is given to the view.
 */
public interface OnTouchListener {
    /**
     * Called when a touch event is dispatched to a view. This allows listeners to
     * get a chance to respond before the target view.
     *
     * @param v The view the touch event has been dispatched to.
     * @param event The MotionEvent object containing full information about
     *        the event.
     * @return True if the listener has consumed the event, false otherwise.
     */
    boolean onTouch(View v, MotionEvent event);
}

注釋說OnTouchListener是一個(gè)接口回調(diào)有送,當(dāng)觸摸事件分發(fā)到該View時(shí)它會(huì)被調(diào)用。\color{#FF0000}{并且這個(gè)回調(diào)會(huì)在觸摸事件給到這個(gè)View之前被調(diào)用僧家。}
emm.從字面意思好像明白點(diǎn)什么
接著看onTouchEvent的:

    /**
     * Implement this method to handle touch screen motion events.
     * <p>
     * If this method is used to detect click actions, it is recommended that
     * the actions be performed by implementing and calling
     * {@link #performClick()}. This will ensure consistent system behavior,
     * including:
     * <ul>
     * <li>obeying click sound preferences
     * <li>dispatching OnClickListener calls
     * <li>handling {@link AccessibilityNodeInfo#ACTION_CLICK ACTION_CLICK} when
     * accessibility features are enabled
     * </ul>
     *
     * @param event The motion event.
     * @return True if the event was handled, false otherwise.
     */
    public boolean onTouchEvent(MotionEvent event) {
//...
}

實(shí)現(xiàn)這個(gè)用法用來處理觸摸屏幕的一些事件動(dòng)作雀摘,如果這個(gè)方法用來檢測(cè)點(diǎn)擊動(dòng)作,通常建議該動(dòng)作由實(shí)現(xiàn)performClick方法發(fā)出八拱。

從以上兩段注釋來看阵赠,姑且可以給個(gè)總結(jié):
onTouch方法用來在進(jìn)行真正的觸摸事件處理之前可以做些額外的事情涯塔。
好像有點(diǎn)攔截的味道。那到底攔截觸摸事件干嘛呢清蚀?觸摸事件之前還有什么要優(yōu)先處理的呢匕荸?
再讀遍上面的總結(jié),其實(shí)核心在于 “攔截觸摸事件處理”枷邪。那觸摸事件到底在處理什么呢每聪,我們?cè)僮屑?xì)看看onTouchEvent的源碼:

    public boolean onTouchEvent(MotionEvent event) {
        final float x = event.getX();
        final float y = event.getY();
        final int viewFlags = mViewFlags;
        final int action = event.getAction();

        final boolean clickable = ((viewFlags & CLICKABLE) == CLICKABLE
                || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
                || (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE;

        if ((viewFlags & ENABLED_MASK) == DISABLED) {
            if (action == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
                setPressed(false);
            }
            mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
            // A disabled view that is clickable still consumes the touch
            // events, it just doesn't respond to them.
            return clickable;
        }
//...

方法開始就進(jìn)行了clickable變量的判斷,如果是DISABLED的直接后面方法不執(zhí)行了齿风,這個(gè)變量作用可太大了药薯,再看其名字,有click字樣救斑,莫非跟點(diǎn)擊事件有關(guān)童本,繼續(xù)往后看:

          if (!focusTaken) {
                 // Use a Runnable and post this rather than calling
                 // performClick directly. This lets other visual state
                  // of the view update before click actions start.
                  if (mPerformClick == null) {
                           mPerformClick = new PerformClick();
                   }
                  if (!post(mPerformClick)) {
                        performClickInternal();
                     }
                  }

果然看到了熟悉的performClick.里面就是很普通的click回調(diào)了:

    public boolean performClick() {
    //...
        final ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnClickListener != null) {
            playSoundEffect(SoundEffectConstants.CLICK);
            li.mOnClickListener.onClick(this);
    //...
    }

\color{#FF0000}{看來我們平常熟悉的點(diǎn)擊事件就是在onTouchEvent里面處理的。}

結(jié)論:
所以onTouchEvent的重要性不言而喻了脸候,那點(diǎn)擊觸摸都有它處理了穷娱,onTouch又有什么用呢?回憶上面的代碼运沦,點(diǎn)擊事件嵌入在onTouchEvent里泵额,比如我們有個(gè)控件只想要觸摸監(jiān)聽,不需要點(diǎn)擊事件携添,那單純的onTouchEvent方法顯然沒法滿足我們的需求嫁盲,此時(shí)onTouch方法就派上用場(chǎng)了。在它里面處理烈掠,結(jié)果返回true羞秤,直接繞過了onTouchEvent里眾多復(fù)雜流程,豈不快哉左敌!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瘾蛋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子矫限,更是在濱河造成了極大的恐慌哺哼,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件叼风,死亡現(xiàn)場(chǎng)離奇詭異取董,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)咬扇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門甲葬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人懈贺,你說我怎么就攤上這事经窖∑碌妫” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵画侣,是天一觀的道長(zhǎng)冰悠。 經(jīng)常有香客問我,道長(zhǎng)配乱,這世上最難降的妖魔是什么溉卓? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮搬泥,結(jié)果婚禮上桑寨,老公的妹妹穿的比我還像新娘。我一直安慰自己忿檩,他們只是感情好尉尾,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著燥透,像睡著了一般沙咏。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上班套,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天肢藐,我揣著相機(jī)與錄音,去河邊找鬼吱韭。 笑死吆豹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的杉女。 我是一名探鬼主播瞻讽,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鸳吸,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼熏挎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起晌砾,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤坎拐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后养匈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哼勇,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年呕乎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了积担。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡猬仁,死狀恐怖帝璧,靈堂內(nèi)的尸體忽然破棺而出先誉,到底是詐尸還是另有隱情,我是刑警寧澤的烁,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布褐耳,位于F島的核電站,受9級(jí)特大地震影響渴庆,放射性物質(zhì)發(fā)生泄漏铃芦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一襟雷、第九天 我趴在偏房一處隱蔽的房頂上張望刃滓。 院中可真熱鬧,春花似錦耸弄、人聲如沸注盈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽老客。三九已至,卻和暖如春震叮,著一層夾襖步出監(jiān)牢的瞬間胧砰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工苇瓣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留尉间,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓击罪,卻偏偏與公主長(zhǎng)得像哲嘲,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子媳禁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容