废话不说,直入主题.
为了实现这个功能,本渣百度了一圈,找到了俩种可执行的方案.
第一种
//开启
SwipeRefreshLayout.post(new Runable(){
@Override
public void run() {
SwipeRefreshLayout.setRefreshing(true);
}
});
//关闭
SwipeRefreshLayout.post(new Runable(){
@Override
public void run() {
SwipeRefreshLayout.setRefreshing(false);
}
});
/* 缺点:不会刷新数据需要手动调用 */
第二种
public class AutoSwipeRefreshView extends SwipeRefreshLayout {
public AutoSwipeRefreshView (Context context) {
super(context);
}
public AutoSwipeRefreshView (Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 自动刷新
*/
public void autoRefresh() {
try {
Field mCircleView = SwipeRefreshLayout.class.getDeclaredField("mCircleView");
mCircleView.setAccessible(true);
View progress = (View) mCircleView.get(this);
progress.setVisibility(VISIBLE);
Method setRefreshing = SwipeRefreshLayout.class.getDeclaredMethod("setRefreshing", boolean.class, boolean.class);
setRefreshing.setAccessible(true);
setRefreshing.invoke(this, true, true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/* 优点:封装后代码优雅,不需要手动请求数据 */
//总结:想要在界面一加载的时候出现更新效果,直接调用setRfreshing(true)是出不来效果的,下为什么setRefreshing(true)没有作用?接下来通过源码看看.
/**
* Notify the widget that refresh state has changed. Do not call this when
* refresh is triggered by a swipe gesture.
*
* @param refreshing Whether or not the view should show refresh progress.
*/
public void setRefreshing(boolean refreshing) {
if (refreshing && mRefreshing != refreshing) {
// scale and show
mRefreshing = refreshing;
int endTarget = 0;
if (!mUsingCustomStart) {
endTarget = (int) (mSpinnerFinalOffset + mOriginalOffsetTop);
} else {
endTarget = (int) mSpinnerFinalOffset;
}
setTargetOffsetTopAndBottom(endTarget - mCurrentTargetOffsetTop,
true /* requires update */);
mNotify = false;
startScaleUpAnimation(mRefreshListener);
} else {
setRefreshing(refreshing, false /* notify */);
}
}
//在onCreate里或onCreateView里调用setRefreshing(),这个时候关键变量mOriginalOffsetTop并没有获取正确的值,下拉效果动画过程中没有显示到正确的坐标,我们在搜索下这个变量看怎么得到的.
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mTarget == null) {
ensureTarget();
}
if (mTarget == null) {
return;
}
mTarget.measure(MeasureSpec.makeMeasureSpec(
getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
getMeasuredHeight() - getPaddingTop() - getPaddingBottom(), MeasureSpec.EXACTLY));
mCircleView.measure(MeasureSpec.makeMeasureSpec(mCircleWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(mCircleHeight, MeasureSpec.EXACTLY));
if (!mUsingCustomStart && !mOriginalOffsetCalculated) {
mOriginalOffsetCalculated = true;
mCurrentTargetOffsetTop = mOriginalOffsetTop = -mCircleView.getMeasuredHeight();
}
mCircleViewIndex = -1;
// Get the index of the circleview.
for (int index = 0; index < getChildCount(); index++) {
if (getChildAt(index) == mCircleView) {
mCircleViewIndex = index;
break;
}
}
}
//如代码所见,是在onMeasure里获取的,根据CircleView的高度来赋值的。所以要解决的方法是让mOriginalOffsetTop能在setRefreshing前正确赋值。
//在onCreate里面调用SwipeRefreshLayout.setRefreshing(ture,true)即可,但是,这个Api是私有的。所以只能用反射或者手动调
//最后一件事,如果使用了第二种方式,注意代码混淆 keep 掉AutoSwipeRefreshView.
//最后一件事,如果使用了第二种方式,注意代码混淆 keep 掉AutoSwipeRefreshView.
//最后一件事,如果使用了第二种方式,注意代码混淆 keep 掉AutoSwipeRefreshView.
//重要的事情要说三遍,因为不keep正式版本是不会自动刷新,debug版本会,很多人会以为是机型问题,别问我是怎么知道的 - -.