TwinklingRefreshLayout v1.04 版精心重構,優化 UI、刷新及越界動畫效果,修復衆多 bug,完美髮布!
TwinklingRefreshLayout延伸了Google的SwipeRefreshLayout的思想,不在列表控件上動刀,而是使用一個ViewGroup來包含列表控件,以保持其較低的耦合性和較高的通用性。其主要特性有:java
支持RecyclerView、ScrollView、AbsListView系列(ListView、GridView)、WebView以及其它能夠獲取到scrollY的控件android
支持加載更多git
默認支持 越界回彈,隨手勢速度有不一樣的效果github
可開啓沒有刷新控件的純淨越界回彈模式web
setOnRefreshListener中擁有大量能夠回調的方法app
將Header和Footer抽象成了接口,並回調了滑動過程當中的係數,方便實現個性化的Header和Footeride
下載Demo函數
You can download the Video for more details.佈局
將libray模塊複製到項目中,或者直接在build.gradle中依賴:
compile 'com.lcodecorex:tkrefreshlayout:1.0.4'
<?xml version="1.0" encoding="utf-8"?> <com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/refreshLayout" android:layout_width="match_parent" android:layout_height="match_parent" app:tr_wave_height="180dp" app:tr_head_height="100dp"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="match_parent" android:overScrollMode="never" android:background="#fff" /> </com.lcodecore.library.TwinklingRefreshLayout>
Android系統爲了跟iOS不同,當界面OverScroll的時候會顯示一個陰影。爲了達到更好的顯示效果,最好禁用系統的overScroll,如上給RecyclerView添加android:overScrollMode="never"
。
refreshLayout.setOnRefreshListener(new RefreshListenerAdapter(){ @Override public void onRefresh(final TwinklingRefreshLayout refreshLayout) { new Handler().postDelayed(new Runnable() { @Override public void run() { refreshLayout.finishRefreshing(); } },2000); } @Override public void onLoadMore(final TwinklingRefreshLayout refreshLayout) { new Handler().postDelayed(new Runnable() { @Override public void run() { refreshLayout.finishLoadmore(); } },2000); } }); }
使用finishRefreshing()方法結束刷新,finishLoadmore()方法結束加載更多。此處OnRefreshListener還有其它方法,能夠選擇須要的來重寫。
若是你想進入到界面的時候主動調用下刷新,能夠調用startRefresh()/startLoadmore()方法。
setWaveHeight 設置頭部可拉伸的最大高度。
setHeaderHeight 頭部固定高度(在此高度上顯示刷新狀態)
setBottomHeight 底部高度
setOverScrollHeight 設置最大的越界高度
靈活的設置是否禁用上下拉。
設置頭部/底部個性化刷新效果,頭部須要實現IHeaderView,底部須要實現IBottomView。
是否容許越界回彈。
是否容許在越界的時候顯示刷新控件,默認是容許的,也就是Fling越界的時候Header或Footer照常顯示,反之就是不顯示;可能有特殊的狀況,刷新控件會影響顯示體驗才設立了這個狀態。
開啓純淨的越界回彈模式,也就是全部刷新相關的View都不顯示,只顯示越界回彈效果
是否在底部越界的時候自動切換到加載更多模式
添加一個固定在頂部的Header(效果還須要優化)
支持切換到像SwipeRefreshLayout同樣的懸浮刷新模式了。
tr_wave_height 頭部拉伸容許的最大高度
tr_head_height 頭部高度
tr_bottom_height 底部高度
tr_overscroll_height 容許越界的最大高度
tr_enable_loadmore 是否容許加載更多,默認爲true
tr_pureScrollMode_on 是否開啓純淨的越界回彈模式
tr_overscroll_top_show - 否容許頂部越界時顯示頂部View
tr_overscroll_bottom_show 是否容許底部越界時顯示底部View
tr_enable_overscroll 是否容許越界回彈
這一點不少相似SwipeRefreshLayout的刷新控件都沒有作到(包括SwipeRefreshLayout),由於沒有攔截下來的時間會傳遞給列表控件,而列表控件的滾動狀態很難獲取。解決方案就是給列表控件設置了OnTouchListener並把事件交給GestureDetector處理,而後在列表控件的OnScrollListener中監聽View是否滾動到了頂部(沒有OnScrollListener的則採用延時監聽策略)。
onPullingDown(TwinklingRefreshLayout refreshLayout, float fraction) 正在下拉的過程
onPullingUp(TwinklingRefreshLayout refreshLayout, float fraction) 正在上拉的過程
onPullDownReleasing(TwinklingRefreshLayout refreshLayout, float fraction) 下拉釋放過程
onPullUpReleasing(TwinklingRefreshLayout refreshLayout, float fraction) 上拉釋放過程
onRefresh(TwinklingRefreshLayout refreshLayout) 正在刷新
onLoadMore(TwinklingRefreshLayout refreshLayout) 正在加載更多
其中fraction表示當前下拉的距離與Header高度的比值(或者當前上拉距離與Footer高度的比值)。
setWaveColor
setRippleColor
setArrowResource
setTextColor
setPullDownStr
setReleaseRefreshStr
setRefreshingStr
setProgressBackgroundColorSchemeResource(@ColorRes int colorRes)
setProgressBackgroundColorSchemeColor(@ColorInt int color)
setColorSchemeResources(@ColorRes int... colorResIds)
setNormalColor(@ColorInt int color)
setAnimatingColor(@ColorInt int color)
更多動效能夠參考AVLoadingIndicatorView庫。
相關接口分別爲IHeaderView和IBottomView,代碼以下:
public interface IHeaderView { View getView(); void onPullingDown(float fraction,float maxHeadHeight,float headHeight); void onPullReleasing(float fraction,float maxHeadHeight,float headHeight); void startAnim(float maxHeadHeight,float headHeight); void reset(); }
其中getView()方法用於在TwinklingRefreshLayout中獲取到實際的Header,所以不能返回null。
實現像新浪微博那樣的刷新效果(有部分修改,具體請看源碼),實現代碼以下:
1.首先定義SinaRefreshHeader繼承自FrameLayout並實現IHeaderView方法
2.getView()方法中返回this
3.在onAttachedToWindow()或者構造函數方法中獲取一下須要用到的佈局
@Override protected void onAttachedToWindow() { super.onAttachedToWindow(); if (rootView == null) { rootView = View.inflate(getContext(), R.layout.view_sinaheader, null); refreshArrow = (ImageView) rootView.findViewById(R.id.iv_arrow); refreshTextView = (TextView) rootView.findViewById(R.id.tv); loadingView = (ImageView) rootView.findViewById(R.id.iv_loading); addView(rootView); } }
4.實現其它方法
@Override public void onPullingDown(float fraction, float maxHeadHeight, float headHeight) { if (fraction < 1f) refreshTextView.setText(pullDownStr); if (fraction > 1f) refreshTextView.setText(releaseRefreshStr); refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180); } @Override public void onPullReleasing(float fraction, float maxHeadHeight, float headHeight) { if (fraction < 1f) { refreshTextView.setText(pullDownStr); refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180); if (refreshArrow.getVisibility() == GONE) { refreshArrow.setVisibility(VISIBLE); loadingView.setVisibility(GONE); } } } @Override public void startAnim(float maxHeadHeight, float headHeight) { refreshTextView.setText(refreshingStr); refreshArrow.setVisibility(GONE); loadingView.setVisibility(VISIBLE); }
5.佈局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <ImageView android:id="@+id/iv_arrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_arrow"/> <ImageView android:id="@+id/iv_loading" android:visibility="gone" android:layout_width="34dp" android:layout_height="34dp" android:src="@drawable/anim_loading_view"/> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="16dp" android:textSize="16sp" android:text="下拉刷新"/> </LinearLayout>
注意fraction的使用,好比上面的代碼refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180)
,fraction * headHeight
表示當前頭部滑動的距離,而後算出它和最大高度的比例,而後乘以180,能夠使得在滑動到最大距離時Arrow剛好能旋轉180度。
onPullingDown/onPullingUp表示正在下拉/正在上拉的過程。
onPullReleasing表示向上拉/下拉釋放時回調的狀態。
startAnim則是在onRefresh/onLoadMore以後纔會回調的過程(此處是顯示了加載中的小菊花)
如上所示,垂手可得就能夠實現一個個性化的Header或者Footer。(更簡單的實現請參考Demo中的 TextHeaderView(圖四))。
製做一個star相關的動效
CoordinateLayout及NestedScroll支持
帶視差效果的Header
第二次重構完成,將核心邏輯拆分爲RefreshProcessor、AnimProcessor、OverScrollProcessor、CoProcessor
優化越界策越,手勢決定越界高度
優化界面流暢度
添加相似SwipeRefreshLayout的懸浮刷新功能(ProgressLayout)
滑到底部自動加載更多or回彈可選,默認爲回彈
容許在結束刷新以前執行一個動效:IHeadView.onFinish(animEndListener)
新增支持Header(Beta)
優化BezierLayout、SinaRefreshLayout等的顯示並增長調節屬性
新增支持設置是否容許OverScroll
修復刷新或加載更多時,列表item沒有鋪滿列表控件,滑動無效的問題
添加主動刷新/加載更多的方法:startRefresh(),startLoadMore()
修復頂部和底部越界高度不一致的問題
修復WebView在底部fling時不能越界的問題
動畫執行時間與高度相關,動效更加柔和
擴展了更多的屬性
修復Fragment回收致使的空指針異常問題
加入x方向判斷,減少了滑動衝突
優化加載更多列表顯示問題
能夠靈活的設置是否禁用上下拉
修復GridView滑動過程當中出現的白條問題
Demo中添加輪播條展現
修復加載更多列表控件的顯示問題
支持了RecyclerView、ScrollView、AbsListView、WebView
支持越界回彈
支持個性化Header、Footer
ps:若有任何問題或者是建議,能夠郵箱聯繫我!(lcodecore@163.com)