android -view基礎

3.1.2.view 的位置

view的位置主要由它的四個頂點來決定,分別對應於view的四個屬性:top、left、right、bottom,

top:左上角縱座標

left: 左上角橫座標

right:右下角橫座標

bottom:右下角縱座標

這些座標都是相對於view的父容器來說的:如圖:

這裏寫圖片描述

通過座標很容易得出view的寬和高

width = right - left

height = bottom-top

關於view的一些屬性的獲取與含義

left = getLeft();

right = getRight();

top = getTop();

bottom = getBottom();

android 3.0後額外的屬性x,y ,translationX,translationY
x,y:是view左上角的座標
translationX,translationY:是View左上角相對於父容器的偏移量,默認值是0

注意:這幾個參數都是相對於父容器的

參數間的關係:

x = left + translationX

y = top + translationY

注意:在View平移的過程中,top, left 是view距離父控件的原始座標,是不會改變的

3.1.3 MotionEvent 和 TouchSlop

1. MotionEvent:是手指接觸屏幕後所產生的一系列事件

ACTION_DOWN — 手指剛接觸屏幕

ACTION_MOVE — 手指在屏幕上移動

ACTION_UP — 手指從屏幕上鬆開的一瞬間

通過MotionEvent 對象可以得到點擊事件過程中發生的x,y 座標

getX();getY(); : 返回的是相對於當前自身View 左上角的x,y 座標

getRawX(); getRawY(); : 返回的是相對於手機屏幕左上角的x,y座標

2.TouchSlop

TouchSlop是系統所能識別出的被認爲是滑動的最小距離,意思是:當滑動的距離小於這個常量值,那麼系統就不認爲是在進行滑動操作,這個常量和設備有關,不同設備上這個值不同

獲取方式:ViewConfiguration.get(getContext()).getScaledTouchSlop();

3.1.4 VelocityTracker GestureDetector 和 Scroller

1.VelocityTracker

速度追蹤,用於追蹤手指在滑動過程中的速度,包括水平和豎直方向的的速度

使用:在View 的onTouchEvent方法中追蹤當前點擊事件的速度

VelocityTracker velocityTracker = VelocityTracker.obtain();

velocityTracker.addMovement(event);
獲取當前的速度:

velocityTracker.computeCurrentVelocity(1000);
int xVelocity = (int) velocityTracker.getXVelocity();

int yVelocity = (int) velocityTracker.getYVelocity();

需要注意:

  1. 獲取速度之前必須先計算速度,即getXVelocity 和 getYVelocity這兩個方法的前面必須使用computeCurrentVelocity()方法
  2. 這裏的速度是指在一段時間內手指所滑過的像素數,比如將時間間隔設爲1000ms,在1s內,手指在水平方向從左向右滑動100像素,那麼水平速度是100,如果手指由右向左滑動,那麼水平速度就爲負數

速度 = (終點位置 - 起點位置)/ 時間段

如果我們通過velocityTracker.computeCurrentVelocity(100);來獲取速度,那麼得到的速度就是手指在100ms內所滑過的像素數,因此水平速度就成了10像素/每100ms,即水平速度爲10,(這裏假設滑動過程爲勻速)
最後當不需要使用時,需要調用clear方法來重置並回收內存

velocityTracker.clear();

velocityTracker.recycle();

2.GestureDetector

手勢檢測,用於輔助檢測用戶的點擊,滑動,長按,雙擊等行爲

3.Scroller

彈性滑動對象,用於實現View的彈性滑動,當使用View的scrollTo/scrollBy方法來進行滑動時,其過程是瞬間完成的,沒有過度效果,用戶體驗不好,這個時候就可以使用Scroller來實現

 Scroller scroller = new Scroller(getContext());
    //緩慢滑動到指定位置
    private void smoothScrollTo(int destX,int dextY){
        int scrollX = getScrollX();
        int delta = destX - scrollX;
        //1000ms內滑向destX ,效果就是緩慢滑動
        mScroller.startScroll(scrollX,0,delta,0,1000);
        invalidate();
    }

    @Override
    public void computeScroll() {
        if(mScroller.computeScrollOffset){
            scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
            postInvalidate();
        }
    }

Scroller 本身並不能實現View的滑動,他需要配合computeScroll()方法才能實現彈性滑動的效果

3.2 View 的滑動

通過三種方式可以實現View的滑動

  1. 通過View自身提供的scrollTo/scrollBy方法

  2. 通過動畫給View施加平移效果來實現滑動

  3. 通過改變View的LayoutParams使的View重新佈局從而實現滑動

3.2.1 使用scrollTo/scrollBy

View的兩個屬性mScrollX ,mScrollY ,這兩個屬性可以通過getScrollX(),getScrollY()得到,mScrollX,mScrollY的單位爲像素,是移動的距離
scrollTo/scrollBy實現view的滑動,只能將view 的內容進行移動,並不能將View本身進行滑動,

這裏寫圖片描述

3.3 彈性滑動

三種方式實現彈性滑動

  1. Scroller

  2. 通過動畫

  3. 使用延時策略

3.4 View的事件分發機制

3.4.1 點擊事件的傳遞規則

事件的分發過程由三個很重要的方法來共同完成dispatchTouchEvent 、onInterceptTouchEvent 、 onTouchEvent

  1. public boolean dispatchTouchEvent(MotionEvent ev)
    用來進行事件的分發

  2. public boolean onInterceptTouchEvent(MotionEvent event)
    在上述方法內部調用,用來判斷是否攔截某個事件,如果當前view攔截了某個事件,那麼在同一個事件序列當中,此方法不會被再次調用,返回結果表示是否攔截當前事件

  3. public boolean onTouchEvent(MotionEvent ev)
    在dispatchTouchEvent 方法中調用,用來處理點擊事件,返回結果表示是否消耗當前事件

以上三個方法的關係用以下僞代碼表示

     public boolean dispatchTouchEvent(MotionEvent ev){
        boolean consume = false;
        if(onInterceptTouchEvent(ev)){
            consumen = onTouchEvent(ev);
        }else{
            consumen = child.dispatchTouchEvent(ev);
        }
        return consume;
    }

注意:
1. viewGroup 默認是不攔截任何事件的,android源碼中viewGroup的onInterceptTouchEvent方法默認返回false
2. view沒有onInterceptTouchEvent方法,一旦有點擊事件傳遞給他,那麼它的onTouchEvent方法就會被調用
3. view的onTouchEvent默認都會消耗事件(返回true),除非它是不可點擊的(clickable 和longClickable 同時爲false).View 的longClickable屬性默認都爲false,clickable 屬性默認爲false

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章