本文主要介绍上拉加载和下拉刷新,Recyclerview实现复杂布局上篇文章已介绍:http://blog.youkuaiyun.com/qq_34501274/article/details/71194958
废话不多说直接进入正文:准备工作都不说了,自己先写好列表,本文主要讲解上拉加载和下拉刷新!
效果图
先看布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/mRecyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
下拉刷新
这个就很简单了,看具体操作!
- 首先给swipeRefreshLayout设置下拉刷新监听
swipeRefreshLayout.setOnRefreshListener(this);
//activity需要实现SwipeRefreshLayout.OnRefreshListener
- 重写onRefresh()方法
/**
* @param ()下拉刷新实现
* */
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
List<HomeModle> newDatas = new ArrayList<HomeModle>();
for (int i = 0; i <6; i++) {
int index = i + 1;
HomeModle homeModle=new HomeModle();
homeModle.setText("new item" + index);
newDatas.add(homeModle);
}
oneAdapter.addItem(newDatas);
swipeRefreshLayout.setRefreshing(false);
Toast.makeText(getActivity(), "更新了6条数据...", Toast.LENGTH_SHORT).show();
}
},3000);
}
这样下拉刷新就完成了!
上拉加载
我们需要在适配器去修改!
思路
1.我们需要在增加一个脚布局,用来显示,正在加载的状态
2.监听recyclerview的滑动状态,当滑倒最后一个条目,仍有上拉状态就让其上拉加载数据
整体的思路就是这两个,下面我们看具体操作getItemCount 总长度需要加上脚布局的 所以需要总长度+1的
- 在getItemViewType(int position)中,增加一个item类型,用来显示上拉加载的布局
// 可以这样写:根据position + 1 == getItemCount()判断,显示完所有列表后,给position+1 就显示上拉加载布局
@Override
public int getItemViewType(int position) {
/**
* 指定position显示返回对应的itemType
* */
if (position == 0) {//轮播图
return TYPE_SLIDER;
} else if (position == 1) {//排行榜图片及查看完整榜单
return TYPE_TYPE2;
} else if (position + 1 == getItemCount()) {//这是为了添加一个footerview
return TYPE_FOOTER;
} else {
return TYPE_TYPE3;
}
}
- 在onCreateViewHolder中加载这个脚布局
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case TYPE_SLIDER://轮播图
return new SliderViewHolder(inflater.inflate(R.layout.home_slider_type, parent, false));
case TYPE_TYPE2:
return new Type2ViewHolder(inflater.inflate(R.layout.home_type2, parent, false));
case TYPE_TYPE3:
return new TypeViewHolder(inflater.inflate(R.layout.home_type3, parent, false));
case TYPE_FOOTER://脚布局(用来显示上拉加载)
return new FooterViewHolder(inflater.inflate(R.layout.footerview, parent, false));
default:
return null;
}
}
//footerview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:gravity="center_vertical"
android:layout_height="wrap_content">
<ProgressBar
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_load"
android:text="正在加载中。。。。。"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content" />
</LinearLayout>
- 可以在onBindViewHolder中设置加载时显示什么
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof SliderViewHolder) {//轮播图
bindItemTypeSlider((SliderViewHolder) holder, position);
} else if (holder instanceof Type2ViewHolder) {//排行榜
bindType2Head((Type2ViewHolder) holder, position);
} else if (holder instanceof TypeViewHolder) {//列表
bindType1((TypeViewHolder) holder, position);
} else if (holder instanceof FooterViewHolder) {//上啦加载
bindFooterView((FooterViewHolder) holder, position);
}
}
bindFooterView
//上拉加载更多
public static final int PULLUP_LOAD_MORE = 0;
//正在加载中
public static final int LOADING_MORE = 1;
/**
* @param holder 上啦加载 显示布局
*/
private void bindFooterView(FooterViewHolder holder, int position) {
FooterViewHolder footerViewHolder = (FooterViewHolder) holder;
switch (load_more_status) {
case PULLUP_LOAD_MORE:
footerViewHolder.tv_load_staus.setText("上拉加载更多...");
break;
case LOADING_MORE:
footerViewHolder.tv_load_staus.setText("正在加载更多数据...");
break;
}
}
- 我们需要在adapter中对外暴露上拉加载的方法
/**
* @param newDatas 下拉刷新时添加数据,要保证最新加载到的数据显示在最前面
* 这里只是用string类型测试,后续需要采用modle。
*/
public void addItem(List<HomeModle> newDatas) {
newDatas.addAll(list3);//先把之前的集合数据添加到这个新集合中。(newDatas,下拉刷新时用户调用,已有新数据,在添加原集合,这样新数据就显示到最前面)
list3.removeAll(list3);//清空这个原有的集合
list3.addAll(newDatas);//
notifyDataSetChanged();
}
/**
* @param loarMoreDatas 上啦加载更多,对外暴露方法
*/
public void addMoreItem(List<HomeModle> loarMoreDatas) {
list3.addAll(loarMoreDatas);
notifyDataSetChanged();
}
/**
* @param status 加载状态,对外暴露方法
*/
public void changeMoreStatus(int status) {
load_more_status = status;
notifyDataSetChanged();
}
界面调用实现上拉加载数据
首先设置recyclerview的滑动监听
//添加滑动监听
mRecyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if(newState ==RecyclerView.SCROLL_STATE_IDLE && lastVisibleItemPosition + 1 ==oneAdapter.getItemCount()){
//上啦加载,添加数据
loarmoreData();
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//获取最后一个条目的位置
lastVisibleItemPosition = gridLayoutManager.findLastVisibleItemPosition();
}
});
/**
* @param () 上啦加载
* */
private void loarmoreData() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
List<HomeModle> loarmoreData = new ArrayList<HomeModle>();
for (int i = 0; i <6; i++) {
HomeModle homeModle=new HomeModle();
int index = i + 1;
homeModle.setText("new item" + index);
loarmoreData.add(homeModle);
}
oneAdapter.addMoreItem(loarmoreData);
oneAdapter.changeMoreStatus(FindAdapter.PULLUP_LOAD_MORE);
//这里调用了addMoreItem ,changeMoreStatus他们内部都刷新了adapter 所以adapter是刷新了两次 ,所以可以把changeMoreStatus,放到addMoreItem 里,其实实现上拉加载数据才是最重要的,至于加载中.加载完成这种状态要不要都行!这需要看个人其实现
Toast.makeText(getActivity(), "上啦加载了6条数据...", Toast.LENGTH_SHORT).show();
}
},2000);
到这里上拉加载就完成了!欢迎吐槽交流!
个人认为,其实自己去实现上拉加载和下拉刷新更简单,功能并不复杂,我们需要第一潜意识是考虑自己怎么实现,而不是第一时间去想,用哪个第三方!要是用第三方,还要去上网去看家怎么实现的!有时候第三方也有很多bug的!