http://blog.csdn.net/dalancon/article/details/46125667
参考了上面链接博主的代码和思路,自己小小的封装了下代码,通用性不强,只针对最普遍使用的的ListView上拉,下拉
SwipeRecyclerViewAdapter继承RecyclerView.Adapter,其实主要为RecyclerView添加一个footerView,并判断加载数据的时机
public abstract class SwipeRecyclerViewAdapter extends RecyclerView.Adapter<ViewHolder>{
private boolean isComplete=false;//是否完成所有数据的加载
private FooterViewHolder footerHolder;
private boolean isFullScreen=false;
protected static final int TYPE_ITEM = 0;
private static final int TYPE_FOOTER = 1;//最后一个item
private static final int TYPE_NULL = -1;
public abstract int GetItemCount();
/**
* @return item的viewHolder
*/
public abstract ViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType);
/**
* bind itemViewHolder
*/
public abstract void onBindItemViewHolder(ViewHolder holder, final int position);
/**
* 完成所有加载
*/
public void completeLoad(){
isComplete=true;
footerHolder.footerRiv.stopRotate();
footerHolder.footerRiv.setVisibility(View.GONE);
footerHolder.footerTv.setVisibility(View.VISIBLE);
}
/**
* 是否完成所有数据的加载
* @return
*/
public boolean isComplete(){
return isComplete;
}
/**
* 重新刷新数据
* @param isComplete
*/
public void refresh() {
isComplete = false;
footerHolder.footerRiv.setVisibility(View.VISIBLE);
footerHolder.footerTv.setVisibility(View.GONE);
}
public boolean isFullScreen() {
return isFullScreen;
}
public void setFullScreen(boolean isFullScreen) {
this.isFullScreen = isFullScreen;
}
@Override
public int getItemCount() {
return GetItemCount() + 1;
}
@Override
public int getItemViewType(int position) {
if(!isFullScreen&&position + 1 == getItemCount()){//当屏幕没有占满的时候,最后一个item用空白view代替footerView
return TYPE_NULL;
}
else if (isFullScreen&&position + 1 == getItemCount()) {// 最后一个item设置为footerView
return TYPE_FOOTER;
}
else {
return TYPE_ITEM;
}
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
if(holder instanceof FooterViewHolder){
FooterViewHolder h = (FooterViewHolder)holder;
if(h.footerRiv.getVisibility()==View.VISIBLE&&!isComplete){
h.footerRiv.startRotate();
}
}else{
onBindItemViewHolder(holder, position);
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_FOOTER) {
View view = LayoutInflater.from(parent.getContext()).inflate(
R.layout.footerview, null);
view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
footerHolder = new FooterViewHolder(view);
return footerHolder;
}
else if(viewType == TYPE_NULL){
return new NullViewHolder(new TextView(parent.getContext()));
}
else if(viewType == TYPE_ITEM){
return onCreateItemViewHolder(parent, viewType);
}
return null;
}
class FooterViewHolder extends ViewHolder {
RotateImageView footerRiv;
TextView footerTv;
public FooterViewHolder(View view) {
super(view);
footerRiv = bind(view, R.id.riv_footer_load);
footerTv = bind(view, R.id.tv_footer_load);
}
}
class NullViewHolder extends ViewHolder {
public NullViewHolder(View view) {
super(view);
}
}
/**
* 绑定ID
*
* @param viewId
* @param <T>
* @return
*/
@SuppressWarnings("unchecked")
public <T extends View> T bind(View v,int viewId) {
View view = v.findViewById(viewId);
return (T) view;
}
}
SwipeRecyclerView继承RecyclerView,并整合了SwipeRefreshLayout的刷新功能,这样只要实现了SwipeRecyclerView的OnRefreshAndLoadListener就可以统一管理下拉刷新和上拉加载了
public class SwipeRecyclerView extends RecyclerView implements OnRefreshListener {
SwipeRecyclerViewAdapter mAdapter;
private LinearLayoutManager mLayoutManager;
private int lastVisibleItem;
private OnRefreshAndLoadListener listener;
private boolean isLoading=false;
public interface OnRefreshAndLoadListener{
/**
* 上拉加载
*/
void onUpLoad();
/**
* 下拉刷新
*/
void onRefresh();
}
/**
* 完成所有加载
*/
public void completeAllLoad(){
mAdapter.completeLoad();
}
/**
* 单次加载
*/
public void completeLoad(){
isLoading=false;
}
public void setOnRefreshAndLoadListener(SwipeRefreshLayout mSwipeRefreshWidget, OnRefreshAndLoadListener listener) {
this.listener = listener;
mSwipeRefreshWidget.setOnRefreshListener(this);
}
public SwipeRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
this.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView,
int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE&&lastVisibleItem + 1 == mAdapter.getItemCount()&&!mAdapter.isComplete()&&!isLoading) {
isLoading=true;
listener.onUpLoad();
}
}
//只有数据满屏的时候才会调用该方法
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();
mAdapter.setFullScreen(true);
}
});
}
@Override
public void setAdapter(Adapter adapter) {
super.setAdapter(adapter);
try{
mAdapter = (SwipeRecyclerViewAdapter)adapter;
}catch(Exception e){
Toast.makeText(this.getContext(), "适配器要继承SwipeRecyclerViewAdapter", 0).show();
}
}
@Override
public void setLayoutManager(LayoutManager layout) {
super.setLayoutManager(layout);
try{
mLayoutManager = (LinearLayoutManager)layout;
}catch(Exception e){
Toast.makeText(this.getContext(), "当前版本只支持LinearLayoutManager", 0).show();
}
}
@Override
public void onRefresh() {
if(mAdapter.isComplete()){//加载过
mAdapter.refresh();//重新加载
}
listener.onRefresh();
}
}
以后使用的过程中,用SwipeRecyclerView替代RecyclerView,用SwipeRecyclerViewAdapter替代RecyclerView.Adapter
这样就可以和SwipeRefreshLayout一起实现简单的上拉加载和下拉刷新了
下面是使用示例:
public class SampleAdapter1 extends SwipeRecyclerViewAdapter {
private List<String> list;
public List<String> getList() {
return list;
}
public SampleAdapter1() {
list = new ArrayList<String>();
}
@Override
public int GetItemCount() {
return list.size();
}
@Override
public ViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_ITEM) {
View view = LayoutInflater.from(parent.getContext()).inflate(
R.layout.list_item_text, null);
view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
return new ItemViewHolder(view);
}
return null;
}
@Override
public void onBindItemViewHolder(ViewHolder holder, int position) {
if (holder instanceof ItemViewHolder) {
((ItemViewHolder) holder).textView.setText(String.valueOf(list
.get(position)));
}
}
class ItemViewHolder extends ViewHolder {
TextView textView;
public ItemViewHolder(View view) {
super(view);
textView = (TextView) view.findViewById(R.id.text);
}
}
}
public class MainActivity extends Activity implements OnRefreshAndLoadListener {
private SwipeRefreshLayout mSwipeRefreshWidget;
private LinearLayoutManager mLayoutManager;
private SwipeRecyclerView mRecyclerView;
private SampleAdapter1 adapter;
private int downCount= 1;
private int upCount = 1;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
Toast.makeText(MainActivity.this, "DOWN", 0).show();
mSwipeRefreshWidget.setRefreshing(false);
// adapter.getList().add(0,"down:"+downCount++);
// adapter.getList().add(0,"down:"+downCount++);
adapter.getList().clear();
initList("refresh",11);
adapter.notifyDataSetChanged();
break;
case 1:
Toast.makeText(MainActivity.this, "UP", 0).show();
adapter.getList().add("up:"+upCount++);
adapter.getList().add("up:"+upCount++);
adapter.getList().add("up:"+upCount++);
mRecyclerView.completeLoad();
if(adapter.getList().size()>15){
mRecyclerView.completeAllLoad();
}
adapter.notifyDataSetChanged();
break;
case 2:
Toast.makeText(MainActivity.this, "first", 0).show();
mSwipeRefreshWidget.setRefreshing(false);
initList("first",11);
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_swipe_refresh);
mSwipeRefreshWidget = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_widget);
mRecyclerView = (SwipeRecyclerView) findViewById(android.R.id.list);
mSwipeRefreshWidget.setColorSchemeResources(R.color.color1, R.color.color2,
R.color.color3, R.color.color4);
// mSwipeRefreshWidget.setOnRefreshListener(this);//不需要再设置刷新功能
mSwipeRefreshWidget.setProgressViewOffset(true, -50, (int) TypedValue
.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources()
.getDisplayMetrics()));
mRecyclerView.setOnRefreshAndLoadListener(mSwipeRefreshWidget,this);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
adapter = new SampleAdapter1();
mRecyclerView.setAdapter(adapter);
mSwipeRefreshWidget.setRefreshing(true);
handler.sendEmptyMessageDelayed(2, 3000);
}
private void initList(String str,int size) {
List<String> list = new ArrayList<String>();
for (int i = 1; i < size; i++) {
list.add(str+":" + i);
}
adapter.getList().addAll(list);
adapter.notifyDataSetChanged();
}
@Override
public void onRefresh() {
handler.sendEmptyMessageDelayed(0, 3000);
}
@Override
public void onUpLoad() {
handler.sendEmptyMessageDelayed(1, 2000);
}
}
布局文件:activity_swipe_refresh.xml
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/swipe_refresh_widget"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.demo.recyclerview.adapter.SwipeRecyclerView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="@null"
android:scrollbars="vertical" />
</android.support.v4.widget.SwipeRefreshLayout>
注意:
如果数据不满屏,这里是不能上拉加载数据的。
下图为效果图