一个比较完整的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); } } }
以上的在继承的时候会要求重写,使用的时候两个类可以直接复制,布局文件就自己写吧,毕竟都不一样。
阅读全文
0 0
- 一个比较完整的RecyclerView上拉下拉控件
- RecyclerView上拉下拉
- 使用SwipeToLoadLayout解决RecyclerView的上拉下拉刷新
- 上拉下拉的原理
- ListView的上拉下拉
- 打造可上拉下拉收起展开+悬浮头部的RecyclerView
- 简单实现上拉下拉,增加头条目和尾条目的RecyclerView
- GPIO的上拉下拉功能说明
- 上拉下拉电阻的作用
- GPIO的上拉下拉功能说明
- 上拉下拉电阻的作用
- GPIO的上拉下拉功能说明
- USB Host的上拉下拉电阻
- GPIO的上拉下拉功能说明
- 设置 PullToRefreshListview的 上拉下拉文字
- GPIO的上拉下拉功能说明
- 最终标准的上拉下拉刷新
- Android 上拉下拉的listVIew
- 唯快不破:linux守护进程的详解与创建
- LaTex长公式换行及对齐
- STM32+CH452驱动8位数码管
- C#工资管理本地数据库连接
- Golang从入门到精通(十二):Golang复合数据之slice
- 一个比较完整的RecyclerView上拉下拉控件
- 黑莓App更新中的坑
- fdafds
- LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 VS2010
- PHP集群中SESSION共享方案之Redis
- 华为解锁码
- js加载文件到div容器中
- 第四周实践项目5 猴子选大王(循环链表)
- js20171213js生成日历