/**
* Copyright 2015 bingoogolapple
* <p/>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cheng.animationstudy.customview.bagrefresh;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.AbsListView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import com.nineoldandroids.animation.ValueAnimator;
import java.lang.reflect.Field;
/**
* 作者:王浩 邮件:bingoogolapple@gmail.com
* 创建时间:15/5/21 22:35
* 描述:下拉刷新、上拉加载更多、可添加自定义(固定、可滑动)头部控件(例如慕课网app顶部的广告位)
*/
public class BGARefreshLayout extends LinearLayout {
private static final String TAG = BGARefreshLayout.class.getSimpleName();
private BGARefreshViewHolder mRefreshViewHolder;
/**
* 整个头部控件,下拉刷新控件mRefreshHeaderView和下拉刷新控件下方的自定义组件mCustomHeaderView的父控件
*/
private LinearLayout mWholeHeaderView;
/**
* 下拉刷新控件
*/
private View mRefreshHeaderView;
/**
* 下拉刷新控件下方的自定义控件
*/
private View mCustomHeaderView;
/**
* 下拉刷新控件下方的自定义控件是否可滚动,默认不可滚动
*/
private boolean mIsCustomHeaderViewScrollable = false;
/**
* 下拉刷新控件的高度
*/
private int mRefreshHeaderViewHeight;
/**
* 当前刷新状态
*/
private RefreshStatus mCurrentRefreshStatus = RefreshStatus.IDLE;
/**
* 上拉加载更多控件
*/
private View mLoadMoreFooterView;
/**
* 上拉加载更多控件的高度
*/
private int mLoadMoreFooterViewHeight;
/**
* 下拉刷新和上拉加载更多代理
*/
private BGARefreshLayoutDelegate mDelegate;
/**
* 手指按下时,y轴方向的偏移量
*/
private int mWholeHeaderDownY = -1;
/**
* 整个头部控件最小的paddingTop
*/
private int mMinWholeHeaderViewPaddingTop;
/**
* 整个头部控件最大的paddingTop
*/
private int mMaxWholeHeaderViewPaddingTop;
/**
* 是否处于正在加载更多状态
*/
private boolean mIsLoadingMore = false;
private AbsListView mAbsListView;
private ScrollView mScrollView;
private RecyclerView mRecyclerView;
private View mNormalView;
private WebView mWebView;
private BGAStickyNavLayout mStickyNavLayout;
private View mContentView;
private float mInterceptTouchDownX = -1;
private float mInterceptTouchDownY = -1;
/**
* 按下时整个头部控件的paddingTop
*/
private int mWholeHeaderViewDownPaddingTop = 0;
/**
* 记录开始下拉刷新时的downY
*/
private int mRefreshDownY = -1;
/**
* 是否已经设置内容控件滚动监听器
*/
private boolean mIsInitedContentViewScrollListener = false;
/**
* 触发上拉加载更多时是否显示加载更多控件
*/
private boolean mIsShowLoadingMoreView = true;
private Handler mHandler;
public BGARefreshLayout(Context context) {
this(context, null);
}
public BGARefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
setOrientation(LinearLayout.VERTICAL);
mHandler = new Handler(Looper.getMainLooper());
initWholeHeaderView();
}
/**
* 初始化整个头部控件
*/
private void initWholeHeaderView() {
mWholeHeaderView = new LinearLayout(getContext());
mWholeHeaderView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
mWholeHeaderView.setOrientation(LinearLayout.VERTICAL);
addView(mWholeHeaderView);
}
@Override
public void onFinishInflate() {
super.onFinishInflate();
if (getChildCount() != 2) {
throw new RuntimeException(BGARefreshLayout.class.getSimpleName() + "必须有且只有一个子控件");
}
mContentView = getChildAt(1);
if (mContentView instanceof AbsListView) {
mAbsListView = (AbsListView) mContentView;
} else if (mContentView instanceof RecyclerView) {
mRecyclerView = (RecyclerView) mContentView;
} else if (mContentView instanceof ScrollView) {
mScrollView = (ScrollView) mContentView;
} else if (mContentView instanceof WebView) {
mWebView = (WebView) mContentView;
} else if (mContentView instanceof BGAStickyNavLayout) {
mStickyNavLayout = (BGAStickyNavLayout) mContentView;
mStickyNavLayout.setRefreshLayout(this);
} else {
mNormalView = mContentView;
// 设置为可点击,否则在空白区域无法拖动
mNormalView.setClickable(true);
}
}
public void setRefreshViewHolder(BGARefreshViewHolder refreshViewHolder) {
mRefreshViewHolder = refreshViewHolder;
mRefreshViewHolder.setRefreshLayout(this);
initRefreshHeaderView();
initLoadMoreFooterView();
}
public void startChangeWholeHeaderViewPaddingTop(int distance) {
ValueAnimator animator = ValueAnimator.ofInt(mWholeHeaderView.getPaddingTop(), mWholeHeaderView.getPaddingTop() - distance);
animator.setDuration(mRefreshViewHolder.getTopAnimDuration());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int paddingTop = (int) animation.getAnimatedValue();
mWholeHeaderView.setPadding(0, paddingTop, 0, 0);
}
});
animator.start();
}
/**
* 初始化下拉刷新控件
*
* @return
*/
private void initRefreshHeaderView() {
mRefreshHeaderView = mRefreshViewHolder.getRefreshHeaderView();
if (mRefreshHeaderView != null) {
mRefreshHeaderView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
mRefreshHeaderViewHeight = mRefreshViewHolder.getRefreshHeaderViewHeight();
mMinWholeHeaderViewPaddingTop = -mRefreshHeaderViewHeight;
mMaxWholeHeaderViewPaddingTop = (int) (mRefreshHeaderViewHeight * mRefreshViewHolder.getSpringDistanceScale());
mWholeHeaderView.setPadding(0, mMinWholeHeaderViewPaddingTop, 0, 0);
mWholeHeaderView.addView(mRefreshHeaderView, 0);
}
}
/**
* 设置下拉刷新控件下方的自定义控件
*
* @param customHeaderView 下拉刷新控件下方的自定义控件
* @param scrollable 是否可以滚动
*/
public void setCustomHeaderView(View customHeaderView, boolean scrollable) {
if (mCustomHeaderView != null && mCustomHeaderView.getParent() != null) {
ViewGroup parent = (ViewGroup) mCustomHeaderView.getParent();
parent.removeView(mCustomHeaderView);
}
mCustomHeaderView = customHeaderView;
if (mCustomHeaderView != null) {
mCustomHeaderView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
mWholeHeaderView.addView(mCustomHeaderView);
mIsCustomHeaderViewScrollable = scrollable;
}
}
/**
* 初始化上拉加载更多控件
*
* @return
*/
private void initLoadMoreFooterView() {
mLoadMoreFooterView = mRefreshViewHolder.getLoadMoreFooterView();
if (mLoadMoreFooterView != null) {
// 测量上拉加载更多控件的高度
mLoadMoreFooterView.measure(0, 0);
mLoadMoreFooterViewHeight = mLoadMoreFooterView.getMeasuredHeight();
mLoadMoreFooterView.setVisibility(GONE);
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
// 被添加到窗口后再设置监听器,这样开发者就不必烦恼先初始化RefreshLayout还是先设置自定义滚动监听器
if (!mIsInitedContentViewScrollListener && mLoadMoreFooterView != null) {
setRecyclerViewOnScrollListener();
setAbsListViewOnScrollListener();
addView(mLoadMoreFooterView, getChildCount());
mIsInitedContentViewScrollListener = true;
}
}
private void setRecyclerViewOnScrollListener() {
if (mRecyclerView != null) {
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if ((newState == RecyclerView.SCROLL_STATE_IDLE || newState == RecyclerView.SCROLL_STATE_SETTLING) && shouldHandleRecyclerViewLoadingMore(mRecyclerView)) {
beginLoadingMore();
}
}
});
}
}
private void setAbsListViewOnScrollListener() {
if (mAbsListView != null) {
try {
// 通过反射获取开发者自定义的滚动监听器,并将其替换成自己的滚动监听器,触发滚动时也要通知开发者自定义的滚动监听器(非侵入式,不让开发者继承特定的控件)
// mAbsListView.getClass().getDeclaredField("mOnScrollListener")获取不到mOnScrollListener,必须通过AbsListView.class.getDeclaredField("mOnScrollListener")获取
Field field = AbsListView.class.getDeclaredField("mOnScrollListener");
field.setAccessible(true);
// 开发者自定义的滚动监听器
final AbsListView.OnScrollListener onScrollListener = (AbsListView.OnScrollListener) field.get(mAbsListView);
mAbsListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int scrollState) {
if ((scrollState == SCROLL_STATE_IDLE || scrollState == SCROLL_STATE_FLING) && shouldHandleAbsListViewLoadingMore(mAbsListView)) {
beginLoadingMore();
}
if (onScrollListener != null) {
onScrollListener.onScrollStateChanged(absListView, scrollState);
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (onScrollListener != null) {
onScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
public boolean shouldHandleAbsListViewLoadingMore(AbsListView absListView) {
if (mIsLoadingMore || mCurrentRefreshStatus == RefreshStatus.REFRESHING || mLoadMoreFooterView == null || mDelegate == null || absListView == null || absListView.getAdapter() == null || absListView.getAdapter().getCount() == 0) {
return false;
}
int lastChildBottom = 0;
if (absListView.getChildCount() > 0) {
// 如果AdapterView的子控件数量不为0,获取最后一个子控件的bottom
lastChildBottom = absListView.getChildAt(absListView.getChildCount() - 1).getBottom();
}
return absListView.getLastVisiblePosition() == absListView.getAdapter().getCount() - 1 && lastChildBottom <= absListView.getMeasuredHeight();
}
public boolean shouldHandleRecyclerViewLoadingMore(RecyclerView recyclerView) {
if (mIsLoadingMore || mCurrentRefreshStatus == RefreshStatus.REFRESHING || mLoadMoreFooterView == null || mDelegate == null || recyclerView.getAdapter() == null || recyclerView.getAdapter().getItemCount() == 0) {
return false;
}
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
if (manager == null || manager.getItemCount() == 0) {
return false;
}
if (manager instanceof LinearLayoutManager) {
LinearLayoutManager layoutManager = (LinearLayoutManager) manager;
if (layoutManager.findLastCompletelyVisibleItemPosition() == recyclerView.getAdapter().getItemCount() - 1) {
return true;
}
} else if (manager instanceof StaggeredGridLayoutManager) {
StaggeredGridLayoutManager layoutManager = (StaggeredGridLayoutManager) manager;
int[] out = layoutManager.findLastCompletelyVisibleItemPositions(null);
int lastPosition = layoutManager.getItemCount() - 1;
for (int position : out) {
if (position == lastPosition) {
return true;
}
}
}
return false;
}
/**
* 是否满足处理刷新的条件
*
* @return
*/
private boolean shouldHandleLoadingMore() {
if (mIsLoadingMore || mCurrentRefreshStatus == RefreshStatus.REFRESHING || mLoadMoreFooterView == null || mDelegate == null) {
return false;
}
// 内容是普通控件,满足
if (mNormalView != null) {
return true;
}
if (BGAScrollingUtil.isWebViewToBottom(mWebView)) {
return true;
}
if (BGAScrollingUtil.isScrollViewToBottom(mScrollView)) {
return true;
}
if (mAbsListView != null) {
return shouldHandleAbsListViewLoadingMore(mAbsListView);
}
if (mRecyclerView != null) {
return shouldHandleRecyclerViewLoadingMore(mRecyclerView);
}
if (mStickyNavLayout != null) {
return mStickyNavLayout.shouldHandleLoadingMore();
}
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mInterceptTouchDownX = event.getRawX();
mInterceptTouchDownY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
if (!mIsLoadingMore && (mCurrentRefreshStatus != RefreshStatus.REFRESHING)) {
if (mInterceptTouchDownX == -1) {
mInterceptTouchDownX = (int) event.getRawX();
}
if (mInterceptTouchDownY == -1) {
mInterceptTouchDownY = (int) event.getRawY();
}
int interceptTouchMoveDistanceY = (int) (event.getRawY() - mInterceptTouchDownY);
// 可以没有上拉加载更多,但是必须有下拉刷新,否则就不拦截事件
if (Math.abs(event.getRawX() - mInterceptTouchDownX) < Math.abs(interceptTouchMoveDistanceY) && mRefreshHeaderView != null) {
if ((interceptTouchMoveDistanceY > 0 && shouldHandleRefresh()) || (interceptTouchMoveDistanceY < 0 && shouldHandleLoadingMore()) || interceptTouchMoveDistanceY < 0 && !isWholeHeaderViewCompleteInvisible()) {
// ACTION_DOWN时没有消耗掉事件,子控件会处于按下状态,这里设置ACTION_CANCEL,使子控件取消按下状态
event.setAction(MotionEvent.ACTION_CANCEL);
super.onInterceptTouchEvent(event);
return true;
}
}
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
// 重置
mInterceptTouchDownX = -1;
mInterceptTouchDownY = -1;
break;
}
return super.onInterceptTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (mIsCustomHeaderViewScrollable && !isWholeHeaderViewCompleteInvisible()) {
super.dispatchTouchEvent(ev);
return true;
}
return super.dispatchTouchEvent(ev);
}
/**
* 是否满足处理刷新的条件
*
* @return
*/
private boolean shouldHandleRefresh() {
if (mIsLoadingMore || mCurrentRefreshStatus == RefreshStatus.REFRESHING || mRefreshHeaderView == null || mDelegate == null) {
return false;
}
// 内容是普通控件,满足
if (mNormalView != null) {
return true;
}
if (BGAScrollingUtil.isScrollViewOrWebViewToTop(mWebView)) {
return true;
}
if (BGAScrollingUtil.isScrollViewOrWebViewToTop(mScrollView)) {
return true;
}
if (BGAScrollingUtil.isAbsListViewToTop(mAbsListView)) {
return true;
}
if (BGAScrollingUtil.isRecyclerViewToTop(mRecyclerView)) {
return true;
}
if (BGAScrollingUtil.isStickyNavLayoutToTop(mStickyNavLayout)) {
return true;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (null != mRefreshHeaderView) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mWholeHeaderDownY = (int) event.getY();
if (mCustomHeaderView != null) {
mWholeHeaderViewDownPaddingTop = mWholeHeaderView.getPaddingTop();
}
if (mCustomHeaderView == null || !mIsCustomHeaderViewScrollable) {
mRefreshDownY = (int) event.getY();
}
if (isWholeHeaderViewCompleteInvisible()) {
mRefreshDownY = (int) event.getY();
return true;
}
break;
case MotionEvent.ACTION_MOVE:
if (handleActionMove(event)) {
return true;
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (handleActionUpOrCancel(event)) {
return true;
}
break;
default:
break;
}
}
return super.onTouchEvent(event);
}
/**
* 自定义头部控件是否已经完全显示
*
* @return true表示已经完全显示,false表示没有完全显示
*/
private boolean isCustomHeaderViewCompleteVisible() {
if (mCustomHeaderView != null) {
// 0表示x,1表示y
int[] location = new int[2];
getLocationOnScreen(location);
int mOnScreenY = location[1];
mCustomHeaderView.getLocationOnScreen(location);
int customHeaderViewOnScreenY = location[1];
if (mOnScreenY <= customHeaderViewOnScreenY) {
return true;
} else {
return false;
}
}
return true;
}
/**
* 整个头部控件是否已经完全隐藏
*
* @return true表示完全隐藏,false表示没有完全隐藏
*/
private boolean isWholeHeaderViewCompleteInvisible() {
if (mCustomHeaderView != null && mIsCustomHeaderViewScrollable) {
// 0表示x,1表示y
int[] location = new int[2];
getLocationOnScreen(location);
int mOnScreenY = location[1];
mWholeHeaderView.getLocationOnScreen(location);
int wholeHeaderViewOnScreenY = location[1];
if (wholeHeaderViewOnScreenY + mWholeHeaderView.getMeasuredHeight() <= mOnScreenY) {
return true;
} else {
return false;
}
}
return true;
}
/**
* 处理手指滑动事件
*
* @param event
* @return true表示自己消耗掉该事件,false表示不消耗该事件
*/
private boolean handleActionMove(MotionEvent event) {
if (mCurrentRefreshStatus == RefreshStatus.REFRESHING || mIsLoadingMore) {
return false;
}
if ((mCustomHeaderView == null || !mIsCustomHeaderViewScrollable) && mRefreshDownY == -1) {
mRefreshDownY = (int) event.getY();
}
if (mCustomHeaderView != null && mIsCustomHeaderViewScrollable && isCustomHeaderViewCompleteVisible() && mRefreshDownY == -1) {
mRefreshDownY = (int) event.getY();
}
int refreshDiffY = (int) event.getY() - mRefreshDownY;
refreshDiffY = (int) (refreshDiffY / mRefreshViewHolder.getPaddingTopScale());
// 如果是向下拉,并且当前可见的第一个条目的索引等于0,才处理整个头部控件的padding
if (refreshDiffY > 0 && shouldHandleRefresh() && isCustomHeaderViewCompleteVisible()) {
int paddingTop = mMinWholeHeaderViewPaddingTop + refreshDiffY;
if (paddingTop > 0 && mCurrentRefreshStatus != RefreshStatus.RELEASE_REFRESH) {
// 下拉刷新控件完全显示,并且当前状态没有处于释放开始刷新状态
mCurrentRefreshStatus = RefreshStatus.RELEASE_REFRESH;
handleRefreshStatusChanged();
mRefreshViewHolder.handleScale(1.0f, refreshDiffY);
} else if (paddingTop < 0) {
// 下拉刷新控件没有完全显示,并且当前状态没有处于下拉刷新状态
if (mCurrentRefreshStatus != RefreshStatus.PULL_DOWN) {
boolean isPreRefreshStatusNotIdle = mCurrentRefreshStatus != RefreshStatus.IDLE;
mCurrentRefreshStatus = RefreshStatus.PULL_DOWN;
if (isPreRefreshStatusNotIdle) {
handleRefreshStatusChanged();
}
}
float scale = 1 - paddingTop * 1.0f / mMinWholeHeaderViewPaddingTop;
/**
* 往下滑
* paddingTop mMinWholeHeaderViewPaddingTop 到 0
* scale 0 到 1
* 往上滑
* paddingTop 0 到 mMinWholeHeaderViewPaddingTop
* scale 1 到 0
*/
mRefreshViewHolder.handleScale(scale, refreshDiffY);
}
paddingTop = Math.min(paddingTop, mMaxWholeHeaderViewPaddingTop);
mWholeHeaderView.setPadding(0, paddingTop, 0, 0);
if (mRefreshViewHolder.canChangeToRefreshingStatus()) {
mWholeHeaderDownY = -1;
mRefreshDownY = -1;
beginRefreshing();
}
return true;
}
if (mCustomHeaderView != null && mIsCustomHeaderViewScrollable) {
if (mWholeHeaderDownY == -1) {
mWholeHeaderDownY = (int) event.getY();
if (mCustomHeaderView != null) {
mWholeHeaderViewDownPaddingTop = mWholeHeaderView.getPaddingTop();
}
}
int wholeHeaderDiffY = (int) event.getY() - mWholeHeaderDownY;
if (!isWholeHeaderViewCompleteInvisible() || (wholeHeaderDiffY > 0 && shouldHandleRefresh() && !isCustomHeaderViewCompleteVisible())) {
int paddingTop = mWholeHeaderViewDownPaddingTop + wholeHeaderDiffY;
if (paddingTop < mMinWholeHeaderViewPaddingTop - mCustomHeaderView.getMeasuredHeight()) {
paddingTop = mMinWholeHeaderViewPaddingTop - mCustomHeaderView.getMeasuredHeight();
}
mWholeHeaderView.setPadding(0, paddingTop, 0, 0);
return true;
}
}
return false;
}
/**
* 处理手指抬起事件
*
* @return true表示自己消耗掉该事件,false表示不消耗该事件
*/
private boolean handleActionUpOrCancel(MotionEvent event) {
boolean isReturnTrue = false;
// 如果当前头部刷新控件没有完全隐藏,则需要返回true,自己消耗ACTION_UP事件
if ((mCustomHeaderView == null || (mCustomHeaderView != null && !mIsCustomHeaderViewScrollable)) && mWholeHeaderView.getPaddingTop() != mMinWholeHeaderViewPaddingTop) {
isReturnTrue = true;
}
if (mCurrentRefreshStatus == RefreshStatus.PULL_DOWN || mCurrentRefreshStatus == RefreshStatus.IDLE) {
// 处于下拉刷新状态,松手时隐藏下拉刷新控件
if (mCustomHeaderView == null || (mCustomHeaderView != null && mWholeHeaderView.getPaddingTop() < 0 && mWholeHeaderView.getPaddingTop() > mMinWholeHeaderViewPaddingTop)) {
hiddenRefreshHeaderView();
}
mCurrentRefreshStatus = RefreshStatus.IDLE;
handleRefreshStatusChanged();
} else if (mCurrentRefreshStatus == RefreshStatus.RELEASE_REFRESH) {
// 处于松开进入刷新状态,松手时完全显示下拉刷新控件,进入正在刷新状态
beginRefreshing();
}
if (mRefreshDownY == -1) {
mRefreshDownY = (int) event.getY();
}
int diffY = (int) event.getY() - mRefreshDownY;
if (shouldHandleLoadingMore() && diffY <= 0) {
// 处理上拉加载更多,需要返回true,自己消耗ACTION_UP事件
isReturnTrue = true;
beginLoadingMore();
}
mWholeHeaderDownY = -1;
mRefreshDownY = -1;
return isReturnTrue;
}
/**
* 处理下拉刷新控件状态变化
*/
private void handleRefreshStatusChanged() {
switch (mCurrentRefreshStatus) {
case IDLE:
mRefreshViewHolder.changeToIdle();
break;
case PULL_DOWN:
mRefreshViewHolder.changeToPullDown();
break;
case RELEASE_REFRESH:
mRefreshViewHolder.changeToReleaseRefresh();
break;
case REFRESHING:
mRefreshViewHolder.changeToRefreshing();
break;
default:
break;
}
}
/**
* 切换到正在刷新状态,会调用delegate的onBGARefreshLayoutBeginRefreshing方法
*/
public void beginRefreshing() {
if (mCurrentRefreshStatus != RefreshStatus.REFRESHING && mDelegate != null) {
mCurrentRefreshStatus = RefreshStatus.REFRESHING;
changeRefreshHeaderViewToZero();
handleRefreshStatusChanged();
mDelegate.onBGARefreshLayoutBeginRefreshing(this);
}
}
/**
* 结束下拉刷新
*/
public void endRefreshing() {
if (mCurrentRefreshStatus == RefreshStatus.REFRESHING) {
mCurrentRefreshStatus = RefreshStatus.IDLE;
hiddenRefreshHeaderView();
handleRefreshStatusChanged();
mRefreshViewHolder.onEndRefreshing();
}
}
/**
* 隐藏下拉刷新控件,带动画
*/
private void hiddenRefreshHeaderView() {
ValueAnimator animator = ValueAnimator.ofInt(mWholeHeaderView.getPaddingTop(), mMinWholeHeaderViewPaddingTop);
animator.setDuration(mRefreshViewHolder.getTopAnimDuration());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int paddingTop = (int) animation.getAnimatedValue();
mWholeHeaderView.setPadding(0, paddingTop, 0, 0);
}
});
animator.start();
}
/**
* 设置下拉刷新控件的paddingTop到0,带动画
*/
private void changeRefreshHeaderViewToZero() {
ValueAnimator animator = ValueAnimator.ofInt(mWholeHeaderView.getPaddingTop(), 0);
animator.setDuration(mRefreshViewHolder.getTopAnimDuration());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int paddingTop = (int) animation.getAnimatedValue();
mWholeHeaderView.setPadding(0, paddingTop, 0, 0);
}
});
animator.start();
}
/**
* 开始上拉加载更多,会触发delegate的onBGARefreshLayoutBeginRefreshing方法
*/
public void beginLoadingMore() {
if (!mIsLoadingMore && mLoadMoreFooterView != null && mDelegate != null && mDelegate.onBGARefreshLayoutBeginLoadingMore(this)) {
mIsLoadingMore = true;
if (mIsShowLoadingMoreView) {
showLoadingMoreView();
}
}
}
/**
* 显示上拉加载更多控件
*/
private void showLoadingMoreView() {
mRefreshViewHolder.changeToLoadingMore();
mLoadMoreFooterView.setVisibility(VISIBLE);
if (mScrollView != null) {
new Handler().post(new Runnable() {
@Override
public void run() {
mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
if (mRecyclerView != null) {
RecyclerView.LayoutManager layoutManager = mRecyclerView.getLayoutManager();
if (mRecyclerView.getAdapter() != null && mRecyclerView.getAdapter().getItemCount() > 0) {
layoutManager.scrollToPosition(mRecyclerView.getAdapter().getItemCount() - 1);
}
}
if (mAbsListView != null) {
if (mAbsListView.getAdapter() != null && mAbsListView.getAdapter().getCount() > 0) {
mAbsListView.scrollBy(0, mLoadMoreFooterViewHeight);
}
}
}
/**
* 结束上拉加载更多
*/
public void endLoadingMore() {
if (mIsLoadingMore) {
if (mIsShowLoadingMoreView) {
// 避免WiFi环境下请求数据太快,加载更多控件一闪而过
mHandler.postDelayed(mDelayHiddenLoadingMoreViewTask, 300);
} else {
mIsLoadingMore = false;
}
}
}
private Runnable mDelayHiddenLoadingMoreViewTask = new Runnable() {
@Override
public void run() {
mIsLoadingMore = false;
mRefreshViewHolder.onEndLoadingMore();
mLoadMoreFooterView.setVisibility(GONE);
if (mAbsListView != null) {
if (mAbsListView.getAdapter() != null && mAbsListView.getAdapter().getCount() > 0) {
mAbsListView.scrollBy(0, -mLoadMoreFooterViewHeight);
}
}
}
};
/**
* 上拉加载更多时是否显示加载更多控件
*
* @param isShowLoadingMoreView
*/
public void setIsShowLoadingMoreView(boolean isShowLoadingMoreView) {
mIsShowLoadingMoreView = isShowLoadingMoreView;
}
public void setDelegate(BGARefreshLayoutDelegate delegate) {
mDelegate = delegate;
}
public interface BGARefreshLayoutDelegate {
/**
* 开始刷新
*/
void onBGARefreshLayoutBeginRefreshing(BGARefreshLayout refreshLayout);
/**
* 开始加载更多。由于监听了ScrollView、RecyclerView、AbsListView滚动到底部的事件,所以这里采用返回boolean来处理是否加载更多。否则使用endLoadingMore方法会失效
*
* @param refreshLayout
* @return 如果要开始加载更多则返回true,否则返回false。(返回false的场景:没有网络、一共只有x页数据并且已经加载了x页数据了)
*/
boolean onBGARefreshLayoutBeginLoadingMore(BGARefreshLayout refreshLayout);
}
public enum RefreshStatus {
IDLE, PULL_DOWN, RELEASE_REFRESH, REFRESHING
}
public static int dp2px(Context context, int dpValue) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, context.getResources().getDisplayMetrics());
}
}