在分析完該庫的源碼時,遇到問題,看了看J_Knight_的MJRefresh源碼解析,確實高屋建甐,境界不一樣,推薦想分析MJRefresh源碼的同學去看看!下面是MJRefresh的github地址,方便查閱。
以下是我在分析源碼時的一點總結,從創建到刷新完成,算是對J_Knight_博客的一點補充吧,比著博客的作者差遠了,就不再賣弄的畫流程圖總結了,走不出作者的高度。剛開始看本庫源碼時覺得作者寫的功能雖然很實用,但是代碼寫的好亂,現在覺得是有點層次太低了,正如博客所說:雖然每個子類中相同的函數被不斷的覆蓋,如setState函數等,但是每個子類的函數都是處理的該子類中定義的控件、實現的功能,這是一種很好的分層的思想,便于使用者繼承后自定義!
說明:
? ? ? ? 1、看這個源碼要明白類繼承he函數覆蓋的概念,在此基礎上才能把各個函數的調用順序理清楚:類繼承之后,子類沒有實現初始化函數,則子類對象調用的初始化函數是基類的,但是但是如果子類覆蓋了基類的函數,那么子類對象調用的就是子類的函數,只不過作者的子類函數都有[super prepare];這句代碼,所以基類中被覆蓋的函數也被調用
? ? ? ? 2、有一點我認為是很不好的,作者在MJRefreshComponent的drawRect函數中寫邏輯,對性能開銷是有影響的。
? ? ? ? 3、分析源碼時請注意庫作者提供的子類樹結構,有助于理解,結構圖如下:
分析MJRefreshNormalHeader
第一部分:實例化、設置屬性
1、首先是為滾動視圖設置下拉視圖,這是從MJRefreshHeader調用了一個初始化配置流程,直接走的是MJRefreshComponent的初始化流程
2、頭視圖建立后通過MJRefreshComponent設置automaticallyChangeAlpha=
3、頭視圖建立后通過MJRefreshStateHeader設置lastUpdatedTimeLabel的字體、顏色等屬性
4、頭視圖建立后通過MJRefreshStateHeader設置stateLabel的字體、顏色等屬性
5、頭視圖建立后通過MJRefreshStateHeader的setTitle:forState:方法設置對應狀態的標題
3-5我得出的結論是頭視圖中的子控件是由哪個“子頭視圖”創建的,其相關設置方法就由哪個“子頭視圖”對外提供
第二部分:將實例化的頭視圖加入父控件
6、調用控件的willMoveToSuperview函數,設置頭視圖的frame,并監聽父視圖scrollView的contentOffset、contentSize、拖拽狀態的改變
第三部分:自動開始刷新
7、頭視圖建立后通過MJRefreshComponent調用beginRefreshing函數開始刷新,函數中設置了pullingPercent、state屬性,通過setNeedsDisplay函數調用頭視圖的drawRect流程
8、drawRect流程設置state屬性,state屬性的設置函數中會根據狀態進行設置,比如此部分會下拉scrollView,并調用layout流程
9、何時收起下拉刷新呢?在用戶傳入的刷新處理函數中,用戶會調用endRefreshing函數設置self.state = MJRefreshStateIdle;,此時在state屬性設置函數中會根據狀態收起下拉刷新
分析MJRefreshBackNormalFooter
看這部分代碼的開始我一直想不通為什么上拉刷新比著下拉刷新在其子類樹中多了MJRefreshBackFooter和MJRefreshAutoFooter這一級,后來想通了。在上拉的MJRefreshHeader函數中實現的功能有“1. 初始化、2. 設置header高度、3. 重新調整y值、4. 通過scrollViewContentOffsetDidChange函數根據contentOffset變化切換狀態、5. 通過setState函數在狀態切換時執行相應操作”這些,但是上拉是分兩種的,所以在MJRefreshFooter中實現的功能為“1. 初始化、2. 設置header高度”,剩余的另外三點在MJRefreshBackFooter和MJRefreshAutoFooter這一級中各自實現各自的。上拉刷新子類樹中剩余的其它類就能跟下拉刷新類比學習了,其大致功能都是一致的,只不過細節不一樣。
第一部分:實例化、設置屬性
1、首先是為滾動視圖設置下拉視圖,這是從MJRefreshFooter調用了一個初始化配置流程,直接走的是MJRefreshComponent的初始化流程
2、頭視圖建立后通過MJRefreshFooter設置ignoredScrollViewContentInsetBottom屬性
第二部分:將實例化的頭視圖加入父控件
3、調用基類和各子類的willMoveToSuperview函數,設置頭視圖的frame,并監聽父視圖scrollView的contentOffset、contentSize、拖拽狀態的改變
第三部分:自動開始刷新
4、頭視圖建立后通過MJRefreshComponent調用beginRefreshing函數開始刷新,函數中設置了pullingPercent、state屬性,通過setNeedsDisplay函數調用頭視圖的drawRect流程
5、drawRect流程設置state屬性,state屬性的設置函數中會根據狀態進行設置,比如此部分會下拉scrollView,并調用layout流程
6、何時收起下拉刷新呢?在用戶傳入的刷新處理函數中,用戶會調用endRefreshing函數設置self.state = MJRefreshStateIdle;,此時在state屬性設置函數中會根據狀態收起下拉刷新