版本号:1.0
日期:2014.4.22
版權:© 2014 kince 轉載注明出處
已經非常接近Path的效果了。還有墨迹天氣的實景也是使用了這種效果:
并且,墨迹天氣用的也是這個開源項目。效果什麼基本都沒改。是以以下重點說一下這個開源項目的實作。
在看它的代碼之前先來分析一下這個效果該怎樣實作,它就是在卷軸框(scrollbar)的旁邊動态顯示一個View。這個View裡面顯示的内容會随着卷軸框的位置變化而變化。一般像帶滑動效果的容器控制都會有卷軸框,比方ScrollView、ListView、GeidView等。那這個卷軸框究竟是什麼呢?它是一個View的屬性,該屬性是繼承view的, 目的設定卷軸框顯示。有以下設定none(隐藏)。horizontal(水準),vertical (垂直)。并非全部的view設定就有效果。 LinearLayout 設定也沒有效果。 要想在超過一屏時拖動效果,在最外層加上ScrollView。并且能夠自己定義卷軸框的樣式和位置。但Path用的并非自己定義的卷軸框,它是在卷軸框旁邊加的View。如圖:
若是在卷軸框的旁邊加入顯示View,首先須要擷取卷軸框的位置,當在滑動的時候在顯示卷軸框的同一時候也讓加入的View顯示出來,也就是說它和卷軸框的顯示是同步的。
那究竟怎樣實作呢。帶着這些疑問看一下源代碼:
通過閱讀源代碼發現,這是一個自己定義的ListView,并且繼承了OnScrollListener接口。這個接口是在AbsListView.java裡面定義的。主要是負責滑動事件的處理,它的代碼例如以下:
OnScrollListener定義了三個常量。分别表示當螢幕停止滾動時為0;當螢幕滾動且使用者使用的觸碰或手指還在螢幕上時為1;由于使用者的操作。螢幕産生慣性滑動時為2。詳細解釋例如以下:
scrollState = 2的這次不回調
//回調順序例如以下
//第1次:scrollState = SCROLL_STATE_TOUCH_SCROLL(1) 正在滾動
//第2次:scrollState = SCROLL_STATE_FLING(2) 手指做了抛的動作(手指離開螢幕前,用力滑了一下)
//第3次:scrollState = SCROLL_STATE_IDLE(0) 停止滾動
//當螢幕停止滾動時為0;當螢幕滾動且使用者使用的觸碰或手指還在螢幕上時為1。
//由于使用者的操作,螢幕産生慣性滑動時為2
//當滾到最後一行且停止滾動時,運作載入
if (isLastRow && scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
//載入元素
......
isLastRow = false;
}
了解完OnScrollListener這個接口再回頭看一下代碼,首先定義了一個回調:
這個用來在Activity中設定監聽事件的,Activity的代碼例如以下:
接着看一下第三個構造方法,由于這個自己定義的ListView定義了自己的屬性。是以須要從attrs檔案裡來取出這些屬性。自己定義的屬性包含三個部分,一是在ListView滑動時彈出的View,二是這個View彈出時的動畫,三是這個View消失時的動畫。然後開始設定這個彈出的View:
看一下設定的方法。
先是調用以下這種方法。從xml檔案裡載入彈出View的布局,在這個地方須要說一下假設自己定義的View不須要手動繪制的話,那麼就能夠使用LayoutInflater去在xml中載入一個已經配置好的視圖,本例中就是使用這個方式。這樣mScrollBarPanel就儲存了彈出的View。然後設定為不可見。使用requestLayout()重新整理一下視圖。再接着就是載入兩個彈出的動畫。特别的。在mOutAnimation動畫中設定了監聽器,在動畫結束的時候設定彈出的View不可見。
回到第三個構造方法中,在第二行設定了super.setOnScrollListener(this),這種方法是效果實作的關鍵。為什麼這麼說。先看一下它的源代碼。
它是在AbsListView中定義的。
設定這種方法後,會傳遞一個OnScrollListener對象給mOnScrollListener,然後調用invokeOnItemScrollListener()方法,它的代碼例如以下:
假設mOnScrollListener不為空的話,就調用mOnScrollListener的onScroll方法。而onScroll方法正是OnScrollListener接口定義的抽象方法,由于我們在ListView中繼承了OnScrollListener接口,重載了onScroll方法,是以将會調用我們自己實作的onScroll方法。就是這樣一個流程。
然後看一下onScroll方法的實作,
上面已經說到。這個onScroll是随着滑動而一直調用的,而我們的需求就是在滑動的時候彈出一個View來。是以這種方法正是處理問題的關鍵位置。能夠在這裡繪制彈出View的視圖。從上面的代碼也能夠看出,就是在這裡進行彈出View大小的計算以及位置的設定等。
最後就是之前說的自己定義ViewGroup的問題了。重載onMeasure()、onLayout()、ondispatchDraw()方法了,這個在本例中也是有所展現的,隻是都比較簡單,相信都看得懂。
可是這幾個方法都是在View初始化的時候調用的,并且僅僅是調用一次。這樣并不适合動态的繪制視圖。是以這也是為什麼本樣例繼承了OnScrollListener,然後在其onScroll方法中去繪制視圖。由于onScroll方法在滑動的時候會調用,是以在滑動的時候就會繪制視圖了。
是以也能夠看出本例採用的是動态畫圖的方式,不是顯示隐藏的方式。
本文轉自mfrbuaa部落格園部落格,原文連結:http://www.cnblogs.com/mfrbuaa/p/5396685.html,如需轉載請自行聯系原作者