自定义RecyclerView实现上拉加载

  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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值