View的事件體系——基本概念及如何實現滑動

View是什麼

View是android中所有控件的基類。

public class View implements Drawable.Callback, KeyEvent.Callback,
        AccessibilityEventSource {

ViewGroup也繼承View,VIewGroup是一組View的集合,就這樣View也可以是單個VIew,也可以是一組view的集合控件,所以這樣就形成了View樹的結構。

View的位置參數

(1)getLeft view左上角相對於父容器的橫座標
(2)gettop view左上角相對於父容器的縱座標
(3)getRight view右下角相對於父容器的橫座標
(4)getBottom view右下角相對於父容器的縱座標
(5)getx view左上角相對於父容器的橫座標
(6)getY view左上角相對於父容器的縱座標
(7)getRawX view左上角相對於屏幕的橫座標
(8)getRawY view左上角相對於屏幕的縱座標
(9)translationX view移動時纔會有的值,默認值爲0,View的左上角相對於父容器的橫向移動的值,也就是view移動的距離
(10)translationY view移動時纔會有的值,默認值爲0,View的左上角相對於父容器的縱向移動的值,也就是view移動的距離
注意:View移動時 view的top、left、right、bottom的值不會變,變化的是x、y,translationX、translationY值。

View移動時的關係如下: X=getLeft+translationX; Y=getRight+translationY;

View的移動時涉及的相關類

(1)MotionEvent:手指觸屏的一系列事件,down、move、up
(2)touchslop:系統識別滑動的最小距離,小於這個距離則不滑動
(3)VelocityTracker:手指的移動速度,速度可以爲負值,主要在View的OnTouchEvent方法中使用

公式:速度=(起點位置-終點位置)/時間

(4)GestureDetector:檢測用的手指事件,主要在View的OnTouchEvent方法中使用,通過實現onGestureListener和onDoubleTapListener兩個接口,就是分辨用戶是點擊、滑動、長按、雙擊等行爲,可以想象成是OnTouchEvent方法中提供的監聽的用戶行爲的另一種實現

綜4所述:監聽用戶的行爲用兩種方式 第一種,常用的OnTouchEvent方法的MotionEvent提供的參數監聽
第二種,View的OnTouchEvent方法中使用GestureDetector,並且
實現onGestureListener和onDoubleTapListener兩個接口進行監聽

View如何實現移動呢?

無彈性的

(1)scrollTo/scrollBy方式(適合交互)
這是view本身提供的,只能移動view的內容的位置,不能移動view在佈局中的位置,也就是view本身不能移動,scrollBy內部調用了scrollTo,這種移動方式不影響點擊事件,移動時關係如下圖:
這裏寫圖片描述

(2)使用動畫(傳統動畫、屬性動畫)(不適合交互)
注意:動畫實際上是改變View的translationX和translationY的值
傳統動畫:就是在Xml中自己實現的動畫配置,在xml中有個fallAfter=“true/false”,true代表影像保留,就是給用戶看到移動到新位置的效果,false代表不保留影像,就是移動後,手指擡起瞬間又回到原來的位置。View的動畫是對View的影像操作,實際不能移動改變View的位置參數,就是用戶看見的是移動到一個新位置,但系統還是認爲View在原來的位置上,所以會造成點擊事件的錯誤,就是新位置沒有點擊事件,
屬性動畫: 在3.0以上纔有屬性,在代碼中動態添加的,通過ObjectAnimator對象,不會有點擊的錯誤出現,

解決點擊事件:傳統動畫的點擊錯誤可以在新位置放置萬一一樣的View,然後移動到新位置的view隱藏,一樣的view顯示出來,就可以解決點擊了。

動畫適合VIew的複雜移動動畫

(3) 改變View的(佈局)LayoutParams參數(適合交互)
如下

 ViewGroup.MarginLayoutParams marginLayoutParams= (ViewGroup.MarginLayoutParams) listView.getLayoutParams();
        marginLayoutParams.width+=100;
        listView.setLayoutParams(marginLayoutParams);

要移動的View的旁邊設置一個0寬高的View,需要移動View時,則可以把0寬度的view設置寬高值,然後就可以把View擠過去 造成移動的效果。

有彈性的

(1)什麼叫彈性移動呢? 無彈性的移動會特別生硬,瞬間就倒手指移動的位置,沒有跟隨的感覺,彈性移動就顯得有活力些
(2)彈性移動的實現原理是什麼呢? 其實就是在一段時間內將一段距離,分成多個小段距離移動疊加完成

實現彈性移動的三種方式

Scroller方式

(1)scroller只是做了將一次大的滑動,分成多個小的滑動,在一段時間完成,分成每塊後,交給View的scrollTo去移動,所以說Scroller並沒有是VIew移動,要配合View的ScrollTo才能實現彈性滑動
(2)scroller具體實現方式:創建scroller對象—>調用scroller的StartScroll()方法,這一步就是將一次大的滑動分成小塊—>調用invalidate()—>調用View.draw重新繪製—>調用重寫的View的方法computeScroll()方法—>調用scroller的computeScrolloffset()方法,獲取滑動的起始點位置信息,同時computeScrolloffset方法返回false代表已經完成,computeScrolloffset是根據時間的流逝百分比算出起始點位置的scrollx和scrolly改變的百分比,並計算出值—>調用view的ScrollTo—>調用postInvalidate()—>調用computeScrolloffset——>重複調用,實現彈性滑動

動畫方式

動畫本身就自帶彈性滑動,就是可以做出更多的動畫效果而已

延時策略

   Handler handler=new Handler(){
        Button button=new Button(MainActivity.this);
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            button.scrollTo(20,0);
            handler.sendEmptyMessageAtTime(1,100);
        }
    };

類似這樣就可以實現移動

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