对于联网类型的应用,通常我们在进入应用时,需要加载数据,并且提示一个加载的进度条。如果使用官方的下拉刷新控件SwipeRefreshLayout本身是带进度条显示功能的,我们自然会想要重用他的进度条。但是如果你想要在onCreate里把他调出来,直接调用setRefreshing()方法是不行的,如下是setRefreshing()方法的源码:
public void setRefreshing( final 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 );
mNotify = false ;
startScaleUpAnimation( mRefreshListener );
} else {
setRefreshing( refreshing , false );
} }
查看源码,可以知道,该方法内部主要是调用了setTargetOffsetTopAndBottom()方法调整进度条的位置来显示的。在没出控件完成onLayout方法之前,位置数据都是不准确的,所以显示不出来很正常。 要解决这个问题很简单 ,把咱们要做的这个事情需要通过post(Runnable runnable)方法放到UI线程排队执行,否则,参数不对,自然显示不出来。 mSwipeRefreshLayout .post( new Runnable() { @Override public void run() { mSwipeRefreshLayout .setRefreshing( true ); } });
当然,也可以把源码提出来将原方法稍微修改一下,一劳永逸。如下:
public void setRefreshing( final boolean refreshing ) {
if ( refreshing && mRefreshing != refreshing ) {
post( new Runnable() {
@Override
public void run() {
// scale and show
mRefreshing = refreshing ;
int endTarget = 0;
if (! mUsingCustomStart ) {
endTarget = ( int ) ( mSpinnerFinalOffset + mOriginalOffsetTop );
} else {
endTarget = ( int ) mSpinnerFinalOffset ;
}
setTargetOffsetTopAndBottom( endTarget - mCurrentTargetOffsetTop , true );
mNotify = false ;
startScaleUpAnimation( mRefreshListener );
}
});
} else {
setRefreshing( refreshing , false );
} }