開發(fā)筆記之打造通用下拉刷新(介紹篇)

開發(fā)筆記之打造通用下拉刷新(介紹篇)
開發(fā)筆記之打造通用下拉刷新(細(xì)節(jié)篇)
開發(fā)筆記之打造通用下拉刷新(重難點篇)

前言

下拉刷新幾乎是移動應(yīng)用最常見的功能了,以前寫一些小應(yīng)用都是直接用別人寫的好的庫狐肢,作為開發(fā)者和初學(xué)者惠爽,我們應(yīng)該要熟悉每個用過的輪子。安卓平臺的下拉刷新瞬哼,最近了解到比較有名的就是超過4000star 的android-Ultra-Pull-To-Refresh 了婚肆。但讓人無奈的是,這么優(yōu)秀的一個庫坐慰,水平有限的我看源碼看得頭暈?zāi)垦=闲裕锩嬗泻芏嗟淖鴺?biāo)判斷和運(yùn)算而且沒有太多的注釋用僧,所以我決定試著自己造一個,于是就有了下面的PullToRefresh(名字比較隨意-_-#)

PullToRefresh

源碼地址: https://github.com/dzysghr/PullToRefresh
通用的可自定義頭部下拉刷新布局赞咙,只實現(xiàn)下拉邏輯责循,不實現(xiàn)下拉頭部視覺效果,功能設(shè)計參考android-Ultra-Pull-To-Refresh 攀操,但有自己特色和優(yōu)化院仿,由于用到了ValueAnimaton,最低只能兼容3.0速和,不斷改進(jìn)中歹垫。當(dāng)然寫這個庫更多的是出于學(xué)習(xí)和研究而不是使用的目的

主要功能特性

  • 下拉松手刷新
  • 下拉刷新
  • 頭部固定
  • 內(nèi)容固定
  • 刷新時是否可拖動頭部
  • 開始刷新時是否強(qiáng)制回到刷新線
  • 刷新完成是否強(qiáng)制返回
  • 刷新時是否隱藏頭部
  • ViewPager等橫向滑動控件共存(效果比android-Ultra-Pull-To-Refresh更好)
  • 自動刷新

Demo

  • 下拉松手刷新
  • 超過刷新線刷新
  • 頭部固定
  • 內(nèi)容固定
  • 刷新時隱藏頭部
  • viewpager等橫向滑動兼容
  • 刷新完成強(qiáng)制返回
  • 自動刷新

功能配置

  • 釋放刷新or下拉刷新(默認(rèn)為false,釋放刷新)
mPullToRefreshLayout.setRefreshImmediately(boolean b);
  • 頭部固定(默認(rèn)為false)
mPullToRefreshLayout.setPinHeader(true);
  • 內(nèi)容固定(默認(rèn)為false,開啟后建議關(guān)閉setCanScrollWhenRefreshing)
mPullToRefreshLayout.setPinContent(true);
  • 刷新完成強(qiáng)制返回(默認(rèn)為false)
mPullToRefreshLayout.setForceToTopWhenFinish(true);
  • 刷新時是否可拖動頭部(默認(rèn)為true)
mPullToRefreshLayout.setCanScrollWhenRefreshing(false);
  • 觸發(fā)刷新時是否強(qiáng)制回到刷新線(默認(rèn)為false)
mPullToRefreshLayout.setUpToRefredshingImmediately(false);
  • 開啟橫向滑動處理(默認(rèn)為false颠放,不處理橫向邏輯)
mPullToRefreshLayout.setHasHorizontalChild(true);
  • 上升動畫時間(默認(rèn)為500ms
mPullToRefreshLayout.setAnimDuration(int animDuration)
  • 滑動阻尼排惨,默認(rèn)為2
mPullToRefreshLayout.setResistance(float resistance)

自定義頭部

  1. 繼承View or ViewGroup ,并實現(xiàn)HeaderController接口碰凶,詳見demo
public interface HeaderController
{

    /**
     * 觸發(fā)刷新的下拉高度,單位px,小于等于你的header高度
     * @return 觸發(fā)刷新的下拉高度
     */
    int getThresholdHeight();

    /**
     * 正在刷新時的高度,單位px暮芭,小于等于你的header高度
     * @return 正在刷新時的高度
     */
    int getRefreshingHeight();

    /**
     * 當(dāng)header的狀態(tài)改變時會調(diào)用
     *
     * @param state 狀態(tài)
     */
    void StateChange(HeaderState state);

    /**
     * 開始刷新時被調(diào)用,這在個方法實現(xiàn)正在刷新時的動畫
     */
    void startRefresh();

    /**
     * 刷新成功時欲低,此方法被調(diào)用
     */
    void onSucceedRefresh();

    /**
     * 刷新失敗時辕宏,此方法被調(diào)用
     */
    void onFailRefresh();

    /**
     * 發(fā)生拖拽時時此方法會被PullToRefreshLayout調(diào)用,可以通過這個偏移量和當(dāng)前的狀態(tài)來決定動畫的樣子
     * @param offset 當(dāng)頭部不固定時表示位置偏移量伸头,當(dāng)頭部內(nèi)容固定時表示頭部露出的高度
     *               范圍為下拉時從 0 到 header.getMeasureHeight,上升反之匾效。**/
    void onPositionChange(float offset);

    /** 當(dāng) Controller被設(shè)置到PullToRefreshLayout時調(diào)用
     * @param layout 關(guān)聯(lián)的PullToRefreshLayout
     */
    void attachLayout(PullToRefreshLayout layout);

}
  1. 為PullToRefhreshLayout設(shè)置頭部
mLayout.setHeader(new CustomHeader(context));

注意事項

  • PullToRefreshLayout只能有一個直接子View,
  • 如果子view是一個可以scroll的控件(比如ListView恤磷、RecycleView面哼、ScrollView),PullToRefreshLayout可以直接判斷子view是否已經(jīng)滑到頂部哮伟,但當(dāng)子view為一個XXLayout內(nèi)部包含一個ListView時
    PullToRefreshLayout
         FrameLauout
             ListView

PullToRefreshLayout是無法判斷Listview是否滑到頂?shù)母藭r需要自己實現(xiàn)何時應(yīng)該開啟下拉

mPullToRefreshLayout.setScrollableListener(new ScrollCondition() {
           @Override
           public boolean canRefresh()
           {
               if(canscroll)
                   return false;
               return true;
           }
       });

后記

其實我個人是不太喜歡看這種瑞士軍刀式的控件源碼的俭茧。因為這個控件的開發(fā)往往沒有太多面向?qū)ο蟮乃枷氩砑ぃ嗟氖亲鴺?biāo)運(yùn)算和判斷悔详,由于它要做到功能強(qiáng)大挪略,可配置性強(qiáng)波材,這樣就導(dǎo)致代碼里有太多的條件分支酿愧,如果做抽象又容易跟進(jìn)去跟著跟著就不知道自己走到哪了游岳,如果一個大方法寫上百行又不可維護(hù)政敢,而我們往往只會用到其中的一種功能,從而使很多判斷是沒必要的胚迫,十分影響對源碼的理解喷户,所以我的代碼里寫了很多注釋,代碼質(zhì)量有待慢慢提高访锻。
不過造輪子還是有好處的褪尝,當(dāng)我寫完這個庫時或者寫的過程到遇到問題闹获,由于有了整體的思路,這時再去看Ultra Pull To Refresh源碼就會感覺邏輯十分清晰河哑,很快就找到關(guān)鍵的代碼所在避诽,這樣一來既可以更深入地理解別人優(yōu)秀的代碼,又可以知道這個東西的坑在哪里但又不會在坑里困擾太久璃谨,這也是造輪子的好處吧沙庐。

后續(xù)更新中...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市睬罗,隨后出現(xiàn)的幾起案子轨功,更是在濱河造成了極大的恐慌,老刑警劉巖容达,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件古涧,死亡現(xiàn)場離奇詭異,居然都是意外死亡花盐,警方通過查閱死者的電腦和手機(jī)羡滑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來算芯,“玉大人柒昏,你說我怎么就攤上這事∥踝幔” “怎么了职祷?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長届囚。 經(jīng)常有香客問我有梆,道長,這世上最難降的妖魔是什么意系? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任泥耀,我火速辦了婚禮,結(jié)果婚禮上蛔添,老公的妹妹穿的比我還像新娘痰催。我一直安慰自己,他們只是感情好迎瞧,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布夸溶。 她就那樣靜靜地躺著,像睡著了一般凶硅。 火紅的嫁衣襯著肌膚如雪蜘醋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天咏尝,我揣著相機(jī)與錄音压语,去河邊找鬼。 笑死编检,一個胖子當(dāng)著我的面吹牛胎食,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播允懂,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼厕怜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蕾总?” 一聲冷哼從身側(cè)響起粥航,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎生百,沒想到半個月后递雀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡蚀浆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年缀程,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片市俊。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡杨凑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出摆昧,到底是詐尸還是另有隱情撩满,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布绅你,位于F島的核電站伺帘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏勇吊。R本人自食惡果不足惜曼追,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望汉规。 院中可真熱鬧礼殊,春花似錦、人聲如沸针史。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽啄枕。三九已至婚陪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間频祝,已是汗流浹背泌参。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工脆淹, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沽一。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓盖溺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親铣缠。 傳聞我的和親對象是個殘疾皇子烘嘱,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容