什么是View
android中的UI界面是由View和ViewGroup組合而成的。View就是屏幕中一個(gè)能進(jìn)行交互的視圖,這里需要弄清楚View和ViewGroup的關(guān)系。ViewGroup是View的子類,即ViewGroup也是一個(gè)View.它相當(dāng)于一個(gè)容器,可以容納若干個(gè)View。舉個(gè)栗子,LinearLayout就是一個(gè)ViewGroup,我們可以在里面放置TextView,Button等。
用一張圖來(lái)表示關(guān)系

View的位置參數(shù)
在Android中, View的位置參數(shù)有它的左上頂點(diǎn)和右下頂點(diǎn)決定,對(duì)應(yīng)View的四個(gè)屬性,left是左上角橫坐標(biāo),top是左上角縱坐標(biāo),right是右下角橫坐標(biāo),bottom是右下角縱坐標(biāo)。** 有一點(diǎn)要注意,這些坐標(biāo)是相對(duì)于父容器而言,它是一種相對(duì)坐標(biāo)。**
Android的x軸和y軸分別向右和向下,原點(diǎn)在左上角。


獲取四個(gè)位置參數(shù)的方法如下
left=getLeft();
top=getTop();
right=getRight();
bottom=getBottom();
得到這四個(gè)參數(shù),計(jì)算view的寬度和高度也就很容易了
width=right-left;
height=bottom-top;
從Android3.0開始,View多了幾個(gè)參數(shù),x,y,translationX,translationY.x和y分別是View左上角的坐標(biāo),而translationX和translationY則是View左上角相對(duì)于父容器的偏移量,比如當(dāng)View產(chǎn)生動(dòng)畫效果時(shí)。translationX和translationY的值就發(fā)生改變,而view的位置參數(shù)是不會(huì)改變的。所以有以下關(guān)系。
x=left+translationX;
y=top+translationY;

MotionEvent和TouchSlop
MotionEvent
我們知道MotionEvent包含三個(gè)基礎(chǔ)事件
- MotionEvent.ACTION_DOWN :手指按下
- MotionEvent.ACTION_UP :手指離開屏幕
- MotionEvent.ACTION_MOVE :手指在屏幕上滑動(dòng)
通過(guò)MotionEvent的對(duì)象我們可以得到點(diǎn)擊事件發(fā)生的x和y坐標(biāo)
getX()和getY()得到的是View左上角的相對(duì)坐標(biāo);而getRawX()和getRawY()返回相對(duì)屏幕左上角的坐標(biāo)。詳見圖二
TouchSlop
TouchSlop是系統(tǒng)所能辨別的最小滑動(dòng)距離,不同設(shè)備的標(biāo)準(zhǔn)有所不同。當(dāng)滑動(dòng)距離小于這個(gè)值時(shí),系統(tǒng)無(wú)法識(shí)別你的滑動(dòng)行為。
獲取這個(gè)常量
ViewConfiguration.get(getContext()).getScaledTouchSlop();
VelocityTraker、GestureDetector
- VelocityTraker
顧名思義,速度追蹤,追蹤手指滑動(dòng)速度,包括水平和豎直方向的速度。在View的onTouchEvent方法中追蹤
VelocityTraker velocityTraker=new VelocityTraker();
velocityTraker.addMovment(event);
然后獲取當(dāng)前速度
velocityTraker.computeCurrentVelocity(1000);
int xVelocity=(int)velocityTraker.getXVolcity();
int yVelocity=(int)velocityTraker.getYVolcity();
要注意,獲取速度前必須計(jì)算速度,即先調(diào)用velocityTraker.computeCurrentVelocity(毫秒);
所謂的速度指單位時(shí)間內(nèi)手指劃過(guò)的像素。
假設(shè)在1s內(nèi),手指水平滑動(dòng)100像素,若將時(shí)間間隔設(shè)置為1000ms,則速度為100像素/s,得到的值就是100;若將時(shí)間間隔設(shè)置為1000ms,則速度為10像素/ms,得到的值為10;即velocityTraker.computeCurrentVelocity(毫秒)設(shè)置的是單位時(shí)間的大小。
公式為
速度=(終點(diǎn)位置-起點(diǎn)位置)/時(shí)間
從上式來(lái)看,速度與滑動(dòng)方向有關(guān),可正可負(fù)。
當(dāng)使用完畢后,需要進(jìn)行回收
velocityTraker.clear();
velocityTraker.recycle();
- GestureDetector
手勢(shì)識(shí)別,用于檢測(cè)用戶的單擊,長(zhǎng)按,滑動(dòng),雙擊等行為.識(shí)別流程如下
觸摸事件MotionEvent--->被OnTouchListener監(jiān)聽到,在其onTouchEvent方法中獲得motionevent對(duì)象--->交給OnGestureListener獲得對(duì)象--->做出反饋
首先我們需要?jiǎng)?chuàng)建GestureDetector并實(shí)現(xiàn)OnGestureListener接口
GestureDetector gestureDetector = new GestureDetector(this);
//解決長(zhǎng)按屏幕后無(wú)法拖動(dòng)的問題
gestureDetector.setIsLongPressEnabled(false);
接著接管View的onTouchEvent方法,在onTouchEvent中
boolean consume = gestureDetector .onTouchEvent(event);
return consume;
接下來(lái)就可以實(shí)現(xiàn)OnGestureListener接口的方法了
| 方法 | 描述 |
|---|---|
| onDown | 手指觸碰的瞬間,由一個(gè)ACTION_DOWN觸發(fā) |
| onShowPress | 手指觸摸屏幕還沒有松開或滑動(dòng)的狀態(tài),由一個(gè)ACTION_DOWN觸發(fā) |
| onSingleTapUp | 手指松開后,由ACTION_UP觸發(fā),是單擊行為 |
| onScroll | 手指滑動(dòng),由ACTION_DOWN和多個(gè)ACTION_MOVE觸發(fā) |
| onLongPress | 長(zhǎng)按 |
| onFling | 快速滑動(dòng),相比onScroll多了ACTION_UP |
| onDoubleTap | 雙擊 |
在開發(fā)中,若是檢測(cè)滑動(dòng)行為,則直接在onTouchEvent實(shí)現(xiàn)就可以
如果想監(jiān)聽長(zhǎng)按,雙擊等行為,則使用 GestureDetector