AndroidView入門(2)View事件

為什么需要要學(xué)習(xí)View事件?

  • 實現(xiàn)涉及滑動的需求
  • 滑動沖突
    本文從以幾個方面講View事件
    View的位置參數(shù)

一 View的位置參數(shù)

View的位置由它的四個頂點決定圈盔,View當(dāng)中有四個屬性與之對應(yīng)top蔓姚、left卓囚、buttom簿盅、right.這四個參數(shù)事相對于父容器的位置轧拄。
在代碼中如何獲取這四個位置呢揽祥?

    private void initView(Context context) {

        //left左上角橫坐標(biāo)
        int left = getLeft();

        //右下角橫坐標(biāo)
        int right = getRight();

        //左上角縱坐標(biāo)
        int top=getTop();

        //右下角縱坐標(biāo)
        int button=getBottom();

    }

Android 3.0 增加了 x、y檩电、translationX拄丰、translationY.
看看代碼中是如何獲取的

    private void intActionTwo() {

        //左上角橫坐標(biāo)
        float x=getX();
        //左上角縱坐標(biāo)
        float y=getY();
        //左上角相對于父容器橫向偏移量
        float translationX=getTranslationX();
        //左上角相對于父容器縱向偏移量
        float translationY=getTranslationY();
    }

注意:
1.translationY府树、translation默認(rèn)值是0
2.換算關(guān)系
x=left+translationX;
y=top+translationY;

二 View的事件分法機制

在講事件的分發(fā)機制之前,先來看看MotionEvent料按、TouchSlop奄侠、VelocityTracker、GestDetector

MotionEvent

觸摸事件對應(yīng)MotionEvent類载矿,指手指觸摸屏幕產(chǎn)生的一系列事件垄潮,常用的有以下幾種:
ActionDown:手指按下的操作,代表觸摸的開始
ActionMove:手指移動超過一定的值會觸發(fā)這個動作
ActionUp:手指離開屏幕的操作闷盔,代表觸摸的結(jié)束

TouchSlop

在滑動的過程中如果小于一定的值弯洗,它就不認(rèn)為是滑動。
這個值用來干么的呢逢勾?
防止誤滑動
注意:這個值不是固定的牡整,不同機型這個值是不同的。
這個值獲取方式:

      int touchSlop = ViewConfiguration.get(this).getScaledTouchSlop();
        Log.e("=======","getScaledTouchSlop:"+touchSlop);

我的手機打印結(jié)果是24

05-26 13:40:16.665 3071-3071/com.myanimation.chen.myviewdemo E/=======: getScaledTouchSlop:24

VelocityTracker

速度追蹤溺拱,追蹤手指在水平或垂直方向上滑動的速度果正。

使用方法

  @Override
    public boolean onTouchEvent(MotionEvent event) {
        VelocityTracker velocityTracker = VelocityTracker.obtain();
        velocityTracker.addMovement(event);
        velocityTracker.computeCurrentVelocity(1000);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:
                int xVeloctiyTracker = (int) velocityTracker.getXVelocity();
                int yVelocityTracker = (int) velocityTracker.getYVelocity();
                Log.e("========vx","xVeloctiyTracker:"+xVeloctiyTracker);
                Log.e("========vy","yVelocityTracker:"+yVelocityTracker);
                break;
            case MotionEvent.ACTION_UP:
                break;
            default:
                break;
        }

        return super.onTouchEvent(event);
    }

第一步 實例化對象,創(chuàng)建VelocityTracker對象
第二步 調(diào)用computCurrentVelocity() 方法計算速度
第三步 獲取水平或垂直方向上的速度

注意:不使用時要回收它

velocityTracker.clear();
velocityTracker.recycle();

GestDetector

手勢檢測盟迟,常用的手勢檢測有:
onSingleTapUp(單擊)
onFling(塊速滑動)
onScroll(拖動)
onLongPress(長按)
onDoubleTap(雙擊)
使用方法:
第一步 實例化對象GestDetector
第二步 解決長按屏幕無法拖動的現(xiàn)象
第三步 接管onTouchEvent()方法
看看Demo

package com.myanimation.chen.myviewdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;

public class MainAty extends AppCompatActivity implements GestureDetector.OnGestureListener {
    private String state = "MainAty";
    private GestureDetector mGestureDetector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.aty_main);

        mGestureDetector=new GestureDetector(this);
        //解決長按屏幕無法拖動的現(xiàn)象
        mGestureDetector.setIsLongpressEnabled(false);
    }




    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean consume=mGestureDetector.onTouchEvent(event);

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_MOVE:

                break;
            case MotionEvent.ACTION_UP:
                break;
            default:
                break;
        }

        return consume;
    }

    @Override
    public boolean onDown(MotionEvent e) {
        Log.e("==========a1","onDown");
        return false;
    }

    @Override
    public void onShowPress(MotionEvent e) {
        Log.e("==========a2","onShowPress");

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        Log.e("==========a3","onSingleTapUp");

        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        Log.e("==========a4","onScroll");

        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {
        Log.e("==========a5","onLongPress");


    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        Log.e("==========a6","onFling");

        return false;
    }
}

點擊事件的分發(fā)規(guī)則由三個方法組成

  • onTouchEvent
  • dispatchTouchEvent
  • onInterceptTouchEvent
public boolean dispatchTouchEvent(MotionEvent ev)

用來進(jìn)行事件分發(fā)秋泳,如果事件能夠傳遞給當(dāng)前的View,此方法一定會運行,下層的dispatchTouchEvent和本層的onTouchEvent受此方法的影響攒菠。
返回true表示當(dāng)前層級消費事件迫皱,false或super.dispatchTouchEvent繼續(xù)往下分發(fā)。

public boolean onInterceptTouchEvent(MotionEvent ev)

用來進(jìn)行事件的攔截辖众,返回true表示攔截事件卓起,false或super.dispatchTouchEveent不攔截繼續(xù)往下分發(fā)。
追蹤手機水平或垂直方向上的速度

public boolean onTouchEvent(MotionEvent e)        

消費事件凹炸,返true表示當(dāng)前層級可以消費事件戏阅,不需要往上傳遞。

Android中擁有事件傳遞能力的組件有三種:
Activity:擁有dispatchTouchEvent啤它、onTouchEvent
ViewGroup:擁有dispatchTouchEvent奕筐、onInterceptTouchEvent、onTouchEvent
View:擁有dispatchTouchEvent变骡、onTouchEvent

三.View的滑動沖突

界面中內(nèi)外兩層同時滑動就會產(chǎn)生滑動沖突
常見常景
常見的滑動沖突可以分為三種

  • 外部滑動方向和內(nèi)部滑動方向不一致
  • 外部滑動方向和內(nèi)部滑動方向一致
  • 上面兩種情況的嵌套

處理規(guī)則

  • 外部滑動方向和內(nèi)部滑動方向不一致
    當(dāng)用戶左右滑動時离赫,需要讓內(nèi)部的View攔截點擊事件,當(dāng)用戶上下滑動時塌碌,需要讓內(nèi)部的View攔截點擊事件渊胸。
  • 外部滑動方向和內(nèi)部滑動方向一致
    在這種情況下就要根據(jù)業(yè)務(wù)來做處理了,滑動到某個地方時台妆,外部View滑動翎猛,某個地方時內(nèi)部View滑動
  • 上面兩種情況的嵌套
    這種情況相對于前面兩種情況要復(fù)雜一點胖翰,這個時候就要把它分解開來,根據(jù)業(yè)務(wù)來做處理
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末切厘,一起剝皮案震驚了整個濱河市萨咳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌迂卢,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件桐汤,死亡現(xiàn)場離奇詭異而克,居然都是意外死亡,警方通過查閱死者的電腦和手機怔毛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門员萍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人拣度,你說我怎么就攤上這事碎绎。” “怎么了抗果?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵筋帖,是天一觀的道長。 經(jīng)常有香客問我冤馏,道長日麸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任逮光,我火速辦了婚禮代箭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘涕刚。我一直安慰自己嗡综,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布杜漠。 她就那樣靜靜地躺著极景,像睡著了一般。 火紅的嫁衣襯著肌膚如雪驾茴。 梳的紋絲不亂的頭發(fā)上戴陡,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音沟涨,去河邊找鬼恤批。 笑死,一個胖子當(dāng)著我的面吹牛裹赴,可吹牛的內(nèi)容都是我干的喜庞。 我是一名探鬼主播诀浪,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼延都!你這毒婦竟也來了雷猪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤晰房,失蹤者是張志新(化名)和其女友劉穎求摇,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體殊者,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡与境,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了猖吴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摔刁。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖海蔽,靈堂內(nèi)的尸體忽然破棺而出共屈,到底是詐尸還是另有隱情,我是刑警寧澤党窜,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布拗引,位于F島的核電站,受9級特大地震影響幌衣,放射性物質(zhì)發(fā)生泄漏寺擂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一泼掠、第九天 我趴在偏房一處隱蔽的房頂上張望怔软。 院中可真熱鬧,春花似錦择镇、人聲如沸挡逼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽家坎。三九已至,卻和暖如春吝梅,著一層夾襖步出監(jiān)牢的瞬間虱疏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工苏携, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留做瞪,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像装蓬,于是被迫代替她去往敵國和親著拭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

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