一个比较完整的RecyclerView上拉下拉控件

来源:互联网 发布:游船上有网络么? 编辑:程序博客网 时间:2024/05/17 06:26

以前写过一个上拉下拉的控件,经过改版之后,有了这篇博客,代码更简洁了,容易理解了。
先上xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal"    android:layout_width="match_parent"    android:id="@+id/id_refresh_layout"    android:layout_height="match_parent">    <android.support.v4.widget.SwipeRefreshLayout        android:id="@+id/id_refresh_view"        android:layout_width="match_parent"        android:layout_height="match_parent">        <android.support.v7.widget.RecyclerView            android:id="@+id/id_loadMore_view"            android:background="@color/line_grey"            android:layout_width="match_parent"            android:layout_height="match_parent">    </android.support.v4.widget.SwipeRefreshLayout></LinearLayout>

然后重写LinearLayout,

/** * @Author Lee * @Date 创建时间 2017/11/9 * @Description 可以时间上拉加载下拉刷新的控件 * @Version 1.0.0 */public class RefreshRecyclerView extends LinearLayout {    private SwipeRefreshLayout RefreshDataView;//下拉刷新控件    private RecyclerView LoadMoreDataView;//上拉加载控件    private int LastVisibleItemPosition;//最后一个可见的item位置    private int PageIndex = 0;//当前的页码    private boolean IsCanLoadData = true;//可以加载数据    public RefreshRecyclerView(Context context) {        super(context);        View view = LayoutInflater.from(context).            inflate(R.layout.refresh_recycler_view, this, true);        __init(view);    }    public RefreshRecyclerView(Context context, AttributeSet attrs) {        super(context, attrs);        View view = LayoutInflater.from(context).            inflate(R.layout.refresh_recycler_view, this, true);        __init(view);    }    public RefreshRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        View view = LayoutInflater.from(context).            inflate(R.layout.refresh_recycler_view, this, true);        __init(view);    }    //初始化控件--双下滑是公司要求,按照自己的方法命名就好    private void __init(View view) {        //Google自带的下拉刷新        RefreshDataView = (SwipeRefreshLayout)view.findViewById(R.id.id_refresh_view);        RefreshDataView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {            @Override            public void onRefresh() {                refreshData();            }        });        //监听RecyclerView 的Scroll事件        LoadMoreDataView = (RecyclerView)view.findViewById(R.id.id_loadMore_view);        LoadMoreDataView.addOnScrollListener(new RecyclerView.OnScrollListener() {            @Override            //网上给的都是有下拉圈圈的,老板要求一个无刷新提示的,不过很菜,下拉快了依旧有卡顿现象,欢迎大神给指点            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {                super.onScrolled(recyclerView, dx, dy);                RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();                //这里是网上搜到的判断不同布局最后一个的可见位置的方法--为了方便以后重写                if (layoutManager instanceof GridLayoutManager) {                    LastVisibleItemPosition = ((GridLayoutManager)layoutManager).                        findLastVisibleItemPosition();                }                else if (layoutManager instanceof StaggeredGridLayoutManager) {                    int[] into = new int[((StaggeredGridLayoutManager)layoutManager).                        getSpanCount()];                    ((StaggeredGridLayoutManager)layoutManager).findLastVisibleItemPositions(into);                    LastVisibleItemPosition = findMax(into);                }                else {                    LastVisibleItemPosition = ((LinearLayoutManager)layoutManager).                        findLastVisibleItemPosition();                }                //上拉滑动距离大于0,当然也可以设置更多, 可见位置判断最后一个加1,(因为加了个底部,提示已经没有了)                if (LastVisibleItemPosition + 1 >= recyclerView.getLayoutManager().getItemCount()                     && dy >= 0) {                    getAndLoadDatas();                }            }        });    }    private int findMax(int[] lastPositions) {        int max = lastPositions[0];        for (int value : lastPositions) {            if (value > max) {                max = value;            }        }        return max;    }    //获取方法    public LRecyclerViewAdapter getAdapter() {        return (LRecyclerViewAdapter) LoadMoreDataView.getAdapter();    }    //提供给使用者设置的方法    public void setAdapter(LRecyclerViewAdapter adapter) {        LoadMoreDataView.setAdapter(adapter);    }    public void setLayoutManager(LinearLayoutManager layoutManager) {        LoadMoreDataView.setLayoutManager(layoutManager);    }    //加载更多方法    private void getAndLoadDatas() {        if (!IsCanLoadData) {            return;        }        IsCanLoadData = false;        //传入当前的页码        getAdapter().getDatas(getLoadPageIndex(), new LRecyclerViewAdapter.IOnData() {            @Override            public void onData(List datas) {                //AssertUtil一个判断是否为空的工具类,网上百度一个就行                if (AssertUtil.isEmpty(datas) && !isFullScreen()) {                    getAdapter().setFootShow(true);                }                else {                    getAdapter().setFootShow(false);                }                RefreshDataView.setRefreshing(false);                if (AssertUtil.isNotEmpty(datas)) {                    IsCanLoadData = true;                    getAdapter().appendData(datas);                }            }        });    }    //判断是否满一屏幕的方法    private boolean isFullScreen() {        return LoadMoreDataView.computeVerticalScrollExtent() >=            LoadMoreDataView.computeVerticalScrollRange();    }    private int getLoadPageIndex() {        return ++PageIndex;    }    //提供外界刷新自主刷新的方法    public void refreshData() {        PageIndex = 0;        getAdapter().clearData();        IsCanLoadData = true;        getAndLoadDatas();    }}

上面有详细的注释了;
最后就是adapter,在这里我重新了一下adapter

/** * @Author Lee * @Date 创建时间 2017/11/9 * @Description * @Version  */public abstract class LRecyclerViewAdapter<T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>  {    private static final int VIEW_TYPE_FOOTER = 0;//加载底部数据    private static final int VIEW_TYPE_ITEM = 1;//加载普通数据    private static final int FOOTER_SHOW = 0;//底部显示    private static final int FOOTER_HIDE = 1;//底部隐藏    private int NowFooterStatus = FOOTER_HIDE;    private List<T> LoadData;    protected LayoutInflater Infalter;    public LRecyclerViewAdapter(Context context, List<T> loadData) {        Infalter = LayoutInflater.from(context);        this.LoadData = loadData;    }    //加载布局    @Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        if (viewType == VIEW_TYPE_FOOTER) {            return new LRecyclerViewAdapter.FooterViewHolder(Infalter.inflate(R.layout.footer_layout, parent, false));        }        else if (viewType == VIEW_TYPE_ITEM) {            return setItemVH(parent);        }        return null;    }    @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {        if(getItemViewType(position) == VIEW_TYPE_ITEM) {            onBindItemViewHolder(holder, position);        }        else {            onBindFooterViewHolder(holder, NowFooterStatus);        }    }    private void onBindFooterViewHolder(RecyclerView.ViewHolder holder, int loadStatus) {        final LRecyclerViewAdapter.FooterViewHolder footerViewHolder = (LRecyclerViewAdapter.FooterViewHolder)holder;        if (loadStatus == FOOTER_SHOW) {            footerViewHolder.mLoadingLayout.setVisibility(View.VISIBLE);            delayedSetFooterGone(footerViewHolder);        }        else {            footerViewHolder.mLoadingLayout.setVisibility(View.GONE);        }    }    private void delayedSetFooterGone(final LRecyclerViewAdapter.FooterViewHolder footerViewHolder) {        new Handler().postDelayed(new Runnable() {            public void run() {                NowFooterStatus = FOOTER_HIDE;                footerViewHolder.mLoadingLayout.setVisibility(View.GONE);            }        }, 2000);    }    //得到总数    @Override    public int getItemCount() {        return LoadData.size() + 1;    }    @Override    public int getItemViewType(int position) {        if (position + 1 == getItemCount()) {            return VIEW_TYPE_FOOTER;        }        return VIEW_TYPE_ITEM;    }    public class FooterViewHolder extends RecyclerView.ViewHolder {        public LinearLayout mLoadingLayout;        public FooterViewHolder(View itemView) {            super(itemView);            mLoadingLayout = (LinearLayout) itemView.findViewById(R.id.id_loading_layout);        }    }    void setData(List<T> data) {        LoadData.clear();        LoadData.addAll(data);        this.notifyDataSetChanged();    }    void appendData(List<T> data) {        LoadData.addAll(data);        this.notifyDataSetChanged();    }    void clearData() {        LoadData.clear();        this.notifyDataSetChanged();    }    void setFootShow(boolean show) {        NowFooterStatus = show ? FOOTER_SHOW : FOOTER_HIDE;    }    public interface IOnData<T> {        void onData(List<T> datas);    }    public abstract void onBindItemViewHolder(final RecyclerView.ViewHolder holder, int position);    public abstract RecyclerView.ViewHolder setItemVH(ViewGroup parent);    public abstract void getDatas(int pageIndex, final IOnData back);}

上面这个可以复制过去直接使用,当然你需要继承这个类来重写其中的一些方法。
之后就是最后的步骤了。:

初始化AdapterDeliverAdapter = new DeliverAddressAdapter(DeliveryAddressListActivity.this, new    ArrayList<DeliveryAddress>());//素质三连,初始化,放adapter,放LayoutManagerLayoutManager = new LinearLayoutManager(DeliveryAddressListActivity.this);RefreshRecycler = (RefreshRecyclerView)findViewById(R.id.receiver);RefreshRecycler.setAdapter(DeliverAdapter);RefreshRecycler.setLayoutManager(LayoutManager);

实现自己的adapter就可以了,代码如下:

class DeliverAddressAdapter extends LRecyclerViewAdapter<DeliveryAddress> {        private List<DeliveryAddress> DeliveryAddress;        public DeliverAddressAdapter(Context context, List<DeliveryAddress> loadData) {            super(context, loadData);            this.DeliveryAddress = loadData;        }        @Override        public void onBindItemViewHolder(RecyclerView.ViewHolder holder,final int position) {            final DeliverAddressVH deliverAddressVH = (DeliverAddressVH)holder;            deliverAddressVH.id_da_address.setText(DeliveryAddress.get(position).                getDa_address());            deliverAddressVH.id_da_consignee.setText(DeliveryAddress.get(position).                getDa_consignee());            deliverAddressVH.id_mobile_phone.setText(DeliveryAddress.get(position).                getDa_consigneetelephone());            deliverAddressVH.id_address_del.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    if (position >= 0 && position < DeliveryAddress.size()) {                        final int da_id = DeliveryAddress.get(position).getDa_id();                        DeliveryAddress.remove(position);                        deleteUserAddress(da_id);                        if (position == 0) {                            DeliverAdapter.notifyDataSetChanged();                        }                        else {                            DeliverAdapter.notifyItemRemoved(position);//推荐用这个                        }                    }                }            });            deliverAddressVH.id_address_edit.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    if (position >= 0 && position < DeliveryAddress.size()) {                        Intent intent = new Intent(DeliveryAddressListActivity.this,                             DeliveryAddressEditActivity.class);                        intent.putExtra("delivery", DeliveryAddress.get(position));                        startActivityForResult(intent, 1);                    }                }            });        }        @Override        public RecyclerView.ViewHolder setItemVH(ViewGroup parent) {            return new DeliverAddressVH(Infalter.inflate(R.layout.delivery_address_item,                 parent, false));        }        @Override        public void getDatas(int pageIndex, IOnData back) {            refreshdata(pageIndex, back);        }        public class DeliverAddressVH extends RecyclerView.ViewHolder {            TextView id_da_address;            TextView id_da_consignee;            TextView id_mobile_phone;            TextView id_address_del;            TextView id_address_edit;            public DeliverAddressVH(View itemView) {                super(itemView);                id_da_address = (TextView) itemView.findViewById(R.id.id_da_address);                id_da_consignee = (TextView) itemView.findViewById(R.id.id_da_consignee);                id_mobile_phone = (TextView) itemView.findViewById(R.id.id_mobile_phone);                id_address_del = (TextView) itemView.findViewById(R.id.id_address_del);                id_address_edit = (TextView) itemView.findViewById(R.id.id_address_edit);            }        }    }

以上的在继承的时候会要求重写,使用的时候两个类可以直接复制,布局文件就自己写吧,毕竟都不一样。

原创粉丝点击