这个效果可以通过最近引入的SwipeRefreshLayout来实现,并且向前兼容到API4了。
使用SwipeRefreshLayout
是一个ViewGroup,但是只能有一个可滑动的视图作为组件,可以是ScrollView或者是ListView和RecyclerView。
ListView
- 首先使用SwipeRefreshLayout包裹ListView
<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipeContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/lvItems"
>
</ListView>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
- 在MainActivity中配置代码
public class MainActivity extends AppCompatActivity {
private SwipeRefreshLayout swipeContainer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//加载swipeContainer的实例
swipeContainer = (SwipeRefreshLayout) findViewById(R.id.swipeContainer);
//设置触发加载数据的监听器
swipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
//放置刷新的代码,确保调用swipeContainer.setRefreshing(false)
//网络请求完成后,
fetchTimelineAsync(0);
}
});
//配置刷新颜色
swipeContainer.setColorSchemeColors(android.R.color.holo_blue_dark,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
}
public void fetchTimelineAsync(int Page) {
//发送网络请求获取更新的数据
//这里的客户端是安卓的Async Http实例
client.getHomeTimeline(0, JsonHttpResponseHandler() {
public void onSuccess(JSONArray json) {
//在加入新数据之前先清除数据
adapter.clear();
//新的数据返回后开始加入列表
adapter.addAll();
//证明刷新完成
swipeContainer.setRefreshing(false);
}
public void onFailure(Throwable e) {
Lod.d("DEBUG", "Fetch timeline error:" + e.toString());
}
});
}
}
3.注意成功的加载后,我们必须示意刷新完成使用setRefreshing(false)
,此外必须注意要在刷新期间清除旧的项,然后添加新的项
RecyclerView
- 像之前那样包裹一层SwipeRefreshLayout
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipeContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rvItems"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
</android.support.v4.widget.SwipeRefreshLayout>
- 更新RecyclerView.adapter确保在适配器中有从当前的数据集中删除数据的方法和加载数据的方法
/* 在RecyclerView.Adapter类中 */
// Clean all elements of the recycler
public void clear() {
items.clear();
notifyDataSetChanged();
}
// Add a list of items
public void addAll(List<list> list) {
items.addAll(list);
notifyDataSetChanged();
}
- 设置SwipeRefreshLayout
同样的向上面一样需要在SwipeRefreshLayout
加一个OnRefreshListener()
通知何时滑动刷新的结束。SwipeRefreshListener
负责通知监听器手势完成,监听器负责正确的决定何时开始刷新内容。
问题
- 只调用
setContentView
一次 - 当加载数据完成后调用
setRefreshing(false)
- 在更新列表前清除数据。