平常使用上拉加载,每次都要写个多重布局来显示”正在加载”与”无更多数据”以及EmptyView。
费时费力,就写了封装类来解决,具体就不多说了,主要代码都加了注释。。。Demo在文章末尾。
BaseRecycleViewAdapter.java
package com.lee.huohuo.configadapter;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.lee.huohuo.R;
import java.util.List;
/**
* @author Lee
* @function 实现RecycleView.Adapter方法
* @date :16/12/12
* @mail [email protected]
*/
public abstract class BaseRecycleViewAdapter<T, M extends ItemRecycleViewHolder> extends RecyclerView.Adapter {
private final int INDEX_CONTENT = 0;
private final int INDEX_FOOTER = 1;
private final int INDEX_EMPTY = 2;
private boolean isShowFooter = true;
private boolean isShowEmpty = false;
public boolean isShowFooter() {
return isShowFooter;
}
public void setShowFooter(boolean showFooter) {
isShowFooter = showFooter;
}
public boolean isShowEmpty() {
return isShowEmpty;
}
public void setShowEmpty(boolean showEmpty) {
isShowEmpty = showEmpty;
}
private List<T> mList;
private Context mContext;
public BaseRecycleViewAdapter(List<T> lists, Context context) {
mList = lists;
mContext = context;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup group, int position) {
View view = null;
RecyclerView.ViewHolder viewHolder = null;
switch (position) {
case INDEX_CONTENT:
//子Adapter抽象来的LayoutID值
view = LayoutInflater.from(mContext).inflate(getItemLayoutId(), group, false);
//子Adapter抽象来的ViewHolder对象
viewHolder = getItemViewHolder(view);
break;
case INDEX_FOOTER:
//如果其子类传了布局ID,那么使用它,否则使用默认布局
view = LayoutInflater.from(mContext).inflate(R.layout.layout_view_footer, group, false);
viewHolder = new _FooterViewHolder(view);
break;
case INDEX_EMPTY:
//使用默认的"数据为空"布局
view = LayoutInflater.from(mContext).inflate(R.layout.layout_view_empty, group, false);
viewHolder = new _EMPTYViewHolder(view);
break;
}
return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
switch (getItemViewType(position)) {
case INDEX_CONTENT:
ItemRecycleViewHolder itemRecycleViewHolder = (ItemRecycleViewHolder) holder;
//将List内的数据以Bean的方式取出
itemRecycleViewHolder.bindHolder(mList.get(position));
itemRecycleViewHolder.getItemRecycleView().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
mOnItemClickListener.OnItemClick(position);
}
}
});
break;
case INDEX_FOOTER:
_FooterViewHolder footerViewHolder = (_FooterViewHolder) holder;
if (isShowFooter()) {
footerViewHolder.viewFooterDoingUpData_LinearLayout.setVisibility(View.VISIBLE);
footerViewHolder.viewFooterNotMoreData_TextView.setVisibility(View.GONE);
if(mOnGetDataListener!=null){
mOnGetDataListener.onGetData();
}
} else {
footerViewHolder.viewFooterDoingUpData_LinearLayout.setVisibility(View.GONE);
footerViewHolder.viewFooterNotMoreData_TextView.setVisibility(View.VISIBLE);
}
break;
case INDEX_EMPTY:
_EMPTYViewHolder emptyViewHolder = (_EMPTYViewHolder) holder;
if (isShowEmpty()) {
emptyViewHolder.view.setVisibility(View.VISIBLE);
} else {
emptyViewHolder.view.setVisibility(View.GONE);
}
break;
}
}
private class _FooterViewHolder extends RecyclerView.ViewHolder {
View view;
LinearLayout viewFooterDoingUpData_LinearLayout;
TextView viewFooterNotMoreData_TextView;
public _FooterViewHolder(View itemView) {
super(itemView);
view = itemView.findViewById(R.id.load_layout);
viewFooterDoingUpData_LinearLayout = (LinearLayout) itemView.findViewById(R.id.viewFooterDoingUpData_LinearLayout);
viewFooterNotMoreData_TextView = (TextView) itemView.findViewById(R.id.viewFooterNotMoreData_TextView);
}
}
private class _EMPTYViewHolder extends RecyclerView.ViewHolder {
View view;
public _EMPTYViewHolder(View itemView) {
super(itemView);
view = itemView.findViewById(R.id.viewEmpty_LinearLayout);
}
}
@Override
public int getItemCount() {
//FooterView和EmptyView只会显示一个,这里进行+1操作
return mList.size() + 1;
}
@Override
public int getItemViewType(int position) {
//当ListSize为0时显示“空”布局
if (mList.size() == 0) {
return INDEX_EMPTY;
}
//当当前position为当前ListSize的最大值时,显示“正在加载”布局
if (mList.size() == position) {
return INDEX_FOOTER;
}
//其它则返回子Adapter布局
return INDEX_CONTENT;
}
public interface OnItemClickListener {
void OnItemClick(int position);
}
private OnItemClickListener mOnItemClickListener;
public void setOnItemClickListener(OnItemClickListener mOnItemClickListener) {
this.mOnItemClickListener = mOnItemClickListener;
}
public interface OnGetDataListener {
void onGetData();
}
private OnGetDataListener mOnGetDataListener;
public void setOnGetDataListener(OnGetDataListener mOnGetDataListener) {
this.mOnGetDataListener = mOnGetDataListener;
}
//抽象方法,得到子Adapter的布局Resource
protected abstract int getItemLayoutId();
//抽象方法,得到子Adapter的ViewHolder对象
protected abstract M getItemViewHolder(View view);
}
因为ItemRecycleViewHolder这个是与子Adapter共用一个对象,所以额外写一个类
ItemRecycleViewHolder.java
package com.lee.huohuo.configadapter;
import android.support.v7.widget.RecyclerView;
import android.view.View;
/**
* @author Lee
* @function 跟BaseRecycleadapter公用
* @date :16/12/12
* @mail 1042372838@qq.com
*/
public abstract class ItemRecycleViewHolder<T> extends RecyclerView.ViewHolder {
private View mView;
public ItemRecycleViewHolder(View v) {
super(v);
mView = v;
}
public View getItemRecycleView() {
return mView;
}
abstract public void bindHolder(T t);
}
MainActivityAdapter.java
package com.lee.huohuo.adapter;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
import com.lee.huohuo.R;
import com.lee.huohuo.configadapter.BaseRecycleViewAdapter;
import com.lee.huohuo.configadapter.ItemRecycleViewHolder;
import com.lee.huohuo.model.MainActivityBean;
import java.util.List;
/**
* Created by lee
* Date 16-12-13.
*/
public class MainActivityAdapter extends BaseRecycleViewAdapter {
//这里为了规范,但没有使用下面两个对象
private List<MainActivityBean> mList;
private Context mContext;
public MainActivityAdapter(List<MainActivityBean> lists, Context context) {
super(lists, context);
mList = lists;
mContext = context;
}
private class MainActivityViewHolder extends ItemRecycleViewHolder<MainActivityBean> {
TextView itemMainActivityUserName_TextView, itemMainActivityPassWord_TextView;
public MainActivityViewHolder(View v) {
super(v);
itemMainActivityUserName_TextView = (TextView) v.findViewById(R.id.itemMainActivityUserName_TextView);
itemMainActivityPassWord_TextView = (TextView) v.findViewById(R.id.itemMainActivityPassWord_TextView);
}
@Override
public void bindHolder(MainActivityBean bean) {
itemMainActivityUserName_TextView.setText(bean.getUsername());
itemMainActivityPassWord_TextView.setText(bean.getPassword());
}
}
@Override
protected int getItemLayoutId() {
//返回给基类布局Resource
return R.layout.item_mainactivity;
}
@Override
protected ItemRecycleViewHolder getItemViewHolder(View view) {
//返回给基类当前Adapter的ViewHolder对象
return new MainActivityViewHolder(view);
}
}
封装的RecycleViewAdapter是把接口开放出来由我们自己去决定是否要进行加载更多以及空Item操作,这里讲解了具体的使用方法
MainActivity.java
package com.lee.huohuo;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.alibaba.fastjson.JSON;
import com.lee.huohuo.adapter.MainActivityAdapter;
import com.lee.huohuo.configadapter.BaseRecycleViewAdapter;
import com.lee.huohuo.model.MainActivityBean;
import org.xutils.common.Callback;
import org.xutils.common.util.LogUtil;
import org.xutils.http.RequestParams;
import org.xutils.view.annotation.ViewInject;
import org.xutils.x;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener {
private String TAG = "MainActivity";
@ViewInject(R.id.mainActivity_RecyclerView)
private RecyclerView mainActivity_RecyclerView;
private LinearLayoutManager layoutManager;
@ViewInject(R.id.mainActivity_SwipeRefreshLayout)
private SwipeRefreshLayout mainActivity_SwipeRefreshLayout;
private MainActivityAdapter mainActivity_Adapter;
private List<MainActivityBean> mainActivityBean_list;
private final int REFRESH_DATATYPE = 0;
private final int UPDATE_DATATYPE = 1;
private int LOAD_PAGE = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//XUtils的注解初始化,为了方便而已
x.view().inject(this);
initValue();
initListener();
//初始化RecycleView数据
getData(REFRESH_DATATYPE);
}
private void initValue() {
mainActivityBean_list = new ArrayList<>();
mainActivity_Adapter = new MainActivityAdapter(mainActivityBean_list, MainActivity.this);
layoutManager = new LinearLayoutManager(MainActivity.this);
//LinearLayoutManager的基本配置,没什么好说的
layoutManager.setOrientation(LinearLayout.VERTICAL);
mainActivity_RecyclerView.setLayoutManager(layoutManager);
mainActivity_RecyclerView.setAdapter(mainActivity_Adapter);
}
private void initListener() {
//SwipeRefreshLayout的监听
mainActivity_SwipeRefreshLayout.setOnRefreshListener(this);
mainActivity_Adapter.setOnItemClickListener(new BaseRecycleViewAdapter.OnItemClickListener() {
@Override
public void OnItemClick(int position) {
Toast.makeText(MainActivity.this, "" + position, Toast.LENGTH_SHORT).show();
}
});
//FooterView默认是显示的,当Adapter的bind开始绘制FooterView时,会回调此接口
mainActivity_Adapter.setOnGetDataListener(new BaseRecycleViewAdapter.OnGetDataListener() {
@Override
public void onGetData() {
getData(UPDATE_DATATYPE);
}
});
//这里有一个不算Bug的Bug,当下拉刷新调用转圈的动画时,立即上滑,会直接崩溃,所以判断当动画正在进行时,让RecycleView不可滑动
mainActivity_RecyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(mainActivity_SwipeRefreshLayout.isRefreshing()){
return true;
}
return false;
}
});
}
private void getData(int type) {
if (type == REFRESH_DATATYPE) {
mainActivityBean_list.clear();
}
RequestParams params = new RequestParams("http://cn.bing.com/");
x.http().post(params, new Callback.CacheCallback<String>() {
@Override
public void onSuccess(String result) {
Log.e(TAG, "MainActivity======onSuccess========" + result);
//请求的bing官网,这里为了方便测试使用本地JSON替换掉网络数据
String localResult = "[{\"username\":\"Tom\",\"password\":\"Tom123456\"},{\"username\":\"Jack\",\"password\":\"Jack123456\"},{\"username\":\"Zach\",\"password\":\"Zach123456\"},{\"username\":\"Jack\",\"password\":\"Jack123456\"},{\"username\":\"Zach\",\"password\":\"Zach123456\"},{\"username\":\"Jack\",\"password\":\"Jack123456\"},{\"username\":\"Zach\",\"password\":\"Zach123456\"},{\"username\":\"Jack\",\"password\":\"Jack123456\"},{\"username\":\"Zach\",\"password\":\"Zach123456\"}]";
List<MainActivityBean> temp_list = JSON.parseArray(localResult, MainActivityBean.class);
mainActivityBean_list.addAll(temp_list);
//记录加载次数
LOAD_PAGE++;
//加载3次之后显示无更多数据,正常的网络数据一般用temp_list.size()==0来判断
if (LOAD_PAGE == 3) {
mainActivity_Adapter.setShowFooter(false);
} else {
mainActivity_Adapter.setShowFooter(true);
}
//因为是本地JSON这里的mainActivityBean_list.size()不会为0,使用的LOAD_PAGE来进行操作
if (mainActivityBean_list.size() == 0) {
mainActivity_Adapter.setShowEmpty(true);
} else {
mainActivity_Adapter.setShowEmpty(false);
}
mainActivity_Adapter.notifyDataSetChanged();
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
Log.e(TAG, "MainActivity======onError========" + ex.getMessage());
}
@Override
public void onCancelled(CancelledException cex) {
Log.e(TAG, "MainActivity======onCancelled========" + cex.getMessage());
}
@Override
public void onFinished() {
mainActivity_SwipeRefreshLayout.setRefreshing(false);
Log.e(TAG, "MainActivity======onFinished========");
}
@Override
public boolean onCache(String result) {
Log.e(TAG, "MainActivity======onCache========" + result);
return false;
}
});
}
@Override
public void onRefresh() {
//LOAD_PAGE重置
LOAD_PAGE = 0;
//在这里进行刷新操作
getData(REFRESH_DATATYPE);
}
}
代码就到这里吧,主要写的是思路,XML布局在项目里面,有需要的可以看看
下载链接:http://download.csdn.net/detail/wx_anonymity/9746461