Android中的SwipeRefreshLayout

在Android的官方v4的包里面有一个import android.support.v4.widget.SwipeRefreshLayout。 官方文demo,可以直接下载源代码download1, download2.

不得不惊叹Google牛x。SwipeRefreshLayout是一个滑动刷新的终极解决方案,可以Swipe任何的的view。也不用重在任何View,使用起来很简单,如下(参考):

<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:text="@string/hello_world"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:gravity="center"/>
    </ScrollView>

</android.support.v4.widget.SwipeRefreshLayout>

只要在任何为外面包裹一层SwipeRefreshLayout,然后在Activity中:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
    swipeLayout.setOnRefreshListener(this);
    swipeLayout.setColorScheme(android.R.color.holo_blue_bright, 
            android.R.color.holo_green_light, 
            android.R.color.holo_orange_light, 
            android.R.color.holo_red_light);
}


@Override 
public void onRefresh() {
    new Handler().postDelayed(new Runnable() {
        @Override public void run() {
            swipeLayout.setRefreshing(false);
        }
    }, 5000);
}

其中这些函数可以用来对其进行一些设置: - setOnRefreshListener(OnRefreshListener):这是开始刷新的回调 - setRefreshing(boolean): 手动设置刷新 - isRefreshing(): 检查是否正在刷新 - setColorScheme(): 设置刷新进度条的动画颜色

需要注意的是,SwipeRefreshLayout默认是对只有一个子控件刷新。如果子View是比较复杂的,例如ListView,你可能需要重载SwipeRefreshLayout.canChildScrollUp()函数来告诉SwipeRefreshLayout它的子View是否可以Scrollup。如果子View可以滑动,就不会出现刷新的动画,否则就出现。例如,如果子View是ListView的话,可以如下重载(参考自官方demo):

@Override
public boolean canChildScrollUp() {
    final AbsListView listView = getListView();
    if (listView.getVisibility() == View.VISIBLE) {
        if (android.os.Build.VERSION.SDK_INT >= 14) {
        // For ICS and above we can call canScrollVertically() to determine this
        return ViewCompat.canScrollVertically(listView, -1);
        } else {
            // Pre-ICS we need to manually check the first visible item 
            // and the child view's top value
            return listView.getChildCount() > 0 &&
                    (listView.getFirstVisiblePosition() > 0
                     || listView.getChildAt(0).getTop() < listView.getPaddingTop());
        }
    } else {
        return false;
    }
}

下拉刷新ListView就实现了。