RecycleView的上拉加载、下拉刷新、EmptyView、setOnItemClickListener的封装

平常使用上拉加载,每次都要写个多重布局来显示”正在加载”与”无更多数据”以及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

猜你喜欢

转载自blog.csdn.net/wx_anonymity/article/details/54847743
今日推荐