自定义RecyclerView实现上拉加载

来源:互联网 发布:淘宝赠运费险什么意思 编辑:程序博客网 时间:2024/05/19 14:51
  1. 为什么要自定义view来实现recylcerview的上拉加载,就为了方便复用,只要写好一次,之后只将要写的类拷贝到新的项目中就能直接使用.不过在xml中必须使用你定义的View,下面直接上代码
/** * 具有上拉加载的recylcerview,默认是没有上拉加载的功能,只有当可见item超过屏幕才会出现上拉加载 * Created by lyf */public class MyRecyclerView extends RecyclerView  {    private boolean isLoadingMore = false; // 是否正在加载更多中, 默认为: false      private OnRefreshLoadListener listener; //回调接口    private boolean  isUp;//是否是向上滑动    public MyRecyclerView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        initFooter(context);    }    public MyRecyclerView(Context context, AttributeSet attrs) {        super(context, attrs);        initFooter(context);    }    public MyRecyclerView(Context context) {        this(context, null);    }    /**     * 初始化     */    public void initFooter(Context context) {        this.setOnScrollListener(new OnScrollListener() {            @Override            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {                super.onScrollStateChanged(recyclerView, newState);                RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();                LinearLayoutManager linearLayoutManager1 = (LinearLayoutManager) layoutManager;                //获取最后一个可见条目的位置                int lastVisibleItem = linearLayoutManager1.findLastVisibleItemPosition();                //获取第一个可见条目的位置                int first = linearLayoutManager1.findFirstVisibleItemPosition();                //屏幕中可见的item个数                int visbleItemCount = lastVisibleItem - first;                //获取总的条目数                int totalItemCount = recyclerView.getAdapter().getItemCount();                //如果可见的条目小于总的条目数,表示数据超过了屏幕,就显示更多加载,才执行loadMore                if(visbleItemCount <totalItemCount - 1 ){                    listener.show(true);                    //等滑倒最后,必须是向上滑动且停止滑动了在加载                    if (newState == RecyclerView.SCROLL_STATE_IDLE                            && lastVisibleItem + 1 == totalItemCount && isUp) {                            //如果没有正在加载中,就执行加载的方法                        if (!isLoadingMore) {                            isLoadingMore = true;                            //回调方法,写你自己加载的逻辑                            listener.loadMore();                        }                    }                }            }            @Override            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                super.onScrolled(recyclerView, dx, dy);                //dy>0 表示向上滑动                if (dy > 0) {                    isUp = true;                }else{                    isUp = false;                }            }        });    }    /**     * 设置是否正在加载     * @param isLoadingMore     */    public void setIsLoadingMore(boolean isLoadingMore) {        this.isLoadingMore = isLoadingMore;    }    /**     * 设置接口     * @param listener     */    public void setOnRefreshLoadListener(OnRefreshLoadListener listener) {        this.listener = listener;    }    /**     * 回调的接口     */    interface OnRefreshLoadListener {        /**         * 加载更多         */        public void loadMore();        /**         * 是否显示最后一个条目         * @param isShow         */        public void  show(boolean isShow);    }}

含有加载更多布局的适配器

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {    private List<Integer> datas;    private Context context;    //加载的几种状态    private static final int STATE = 0;  //默认状态    private static final int ERROR = 1;  //加载失败    private static final int EMPTY = 2;  //加载成功,但数据为空    private int loading; //加载的状态    private  boolean isShow;//是否显示加载更多    //几种类型的条目    private static final int TYPE_ITEM = 0;    private static final int TYPE_FOOTER = 1;    public MyRecyclerViewAdapter(Context context, List<Integer> datas) {        this.datas = datas;        this.context = context;    }    @Override    public int getItemViewType(int position) {        // 最后一个item设置为footerView  ,主要是调用的getItemCount        if (position + 1 == getItemCount()) {            return TYPE_FOOTER;        } else {            return TYPE_ITEM;        }    }    /**     * 创建view调用的方法     * @param parent     * @param viewType view的类型     * @return     */    @Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        if (viewType == TYPE_ITEM) { //如果是条目            View view = LayoutInflater.from(context).inflate(R.layout.layout_item, parent, false);            MyViewHolder viewHolder = new MyViewHolder(view);            return viewHolder;        } else if (viewType == TYPE_FOOTER) {//如果是最后一个条目            //必须用这个加载view 否则会不对            View view = LayoutInflater.from(context).inflate(R.layout.refresh_footer_view, parent, false);            LoadHolder loadHolder = new LoadHolder(view);            return loadHolder;        }        return null;    }    /**     * 绑定数据     * @param holder     * @param position     */    @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {        if (holder instanceof MyViewHolder) {            MyViewHolder myViewHolder = (MyViewHolder) holder;            myViewHolder.mTextView.setText(position + "");        } else if (holder instanceof LoadHolder) {            LoadHolder loadHolder = (LoadHolder) holder;            //默认更多加载不显示            if (isShow){                loadHolder.ll_refresh.setVisibility(View.VISIBLE);            }else{                loadHolder.ll_refresh.setVisibility(View.GONE);            }            switch (loading) {                case STATE:                    loadHolder.progressBar.setVisibility(View.VISIBLE);                    loadHolder.title.setText("加载中,请稍后...");                    break;                case ERROR:                    loadHolder.progressBar.setVisibility(View.GONE);                    loadHolder.title.setText("加载失败");                    break;                case EMPTY:                    loadHolder.progressBar.setVisibility(View.GONE);                    loadHolder.title.setText("没有更多数据");                    break;            }        }    }    @Override    public int getItemCount() {        return datas.size() + 1;    }    public void setIsShow(boolean isShow) {        this.isShow = isShow;    }    /**     * 设置加载的状态     *     * @param loading     */    public void setLoading(int loading) {        this.loading = loading;    }}/** * 正常条目的holder */class MyViewHolder extends RecyclerView.ViewHolder {    TextView mTextView;    public MyViewHolder(View itemView) {        super(itemView);        mTextView = (TextView) itemView.findViewById(R.id.item_tv);    }}/** * 加载更多的view */class LoadHolder extends RecyclerView.ViewHolder {    TextView title;    ProgressBar progressBar;    LinearLayout ll_refresh; //加载更多的布局    public LoadHolder(View itemView) {        super(itemView);        title = (TextView) itemView.findViewById(R.id.tv_refresh_footer);        progressBar = (ProgressBar) itemView.findViewById(R.id.progressBar);        ll_refresh = (LinearLayout) itemView.findViewById(R.id.ll_refresh);    }}

下面是加载更多的xml布局:

   <<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:id="@+id/ll_refresh"    android:layout_height="48dp"    android:background="#fff"    android:gravity="center"    android:visibility="gone"    android:orientation="horizontal" >    <ProgressBar        android:id="@+id/progressBar"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_margin="10dip"        android:indeterminateDrawable="@drawable/custom_progressbar" />    <TextView        android:id="@+id/tv_refresh_footer"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginLeft="10dip"        android:text="加载中,请稍后"        android:textColor="#cccccc"        android:textSize="15sp" /></LinearLayout>

java代码:

  mRecyclerView = (MyRecyclerView) this.findViewById(R.id.recyclerView);        datas = new ArrayList<>();        linearLayoutManager = new LinearLayoutManager(this);        mRecyclerView.setLayoutManager(linearLayoutManager);        //给recyclerview设置item增加,删除动画效果        mRecyclerView.setItemAnimator(new DefaultItemAnimator());        for (int i = 0; i < 10; i++) {            datas.add(i);        }        adapter = new MyRecyclerViewAdapter(this, datas);        mRecyclerView.setAdapter(adapter);        //设置加载更多        mRecyclerView.setOnRefreshLoadListener(this); /**     * 加载更多的回调方法     */    public void loadMore() {            在这里写你上拉加载的逻辑,只是当你加载完成以后需要调用下面的代码 ,还有就是可以在这里通过adapter.setLoading(0)方法来设置加载的状态,0表示加载成功,1表示加载失败,2表示加载成功,但是数据为空                       //设置加载完了                       mRecyclerView.setIsLoadingMore(false);    }    /**     * 是否显示更多加载的回调方法     * @param isShow     */    @Override    public void show(boolean isShow) {        当isShow为true时,表示recylcerview的条目超过屏幕,可以显示加载更多的布局,在适配器中默认是不显示加载更多的布局的,可以通过下面的代码让它显示.        adapter.setIsShow(isShow);        //刷新加载更多这一个条目        adapter.notifyItemRangeChanged(0,adapter.getItemCount());    }

2.只要将上面3个类创建好就可以实现recylcerview的上拉加载效果,且如果recylcerview的条目个数没有超过屏幕时,上拉加载的布局就不会显示,上拉加载的功能也不能使用.且可以在loadmore回调方法中根据服务器返回的状态来设置加载更多的状态.

0 0
原创粉丝点击