RecyclerView下拉刷新与上拉加载

您所在的位置:网站首页 下拉可以刷新待取件 RecyclerView下拉刷新与上拉加载

RecyclerView下拉刷新与上拉加载

2024-07-17 03:45:28| 来源: 网络整理| 查看: 265

转载:【江清清的博客】

目录 SwipeRefrshLayoutRecyclerView+SwpieRefreshLayout实现下拉刷新效果布局文件onRefresh()RecyclerView.Adapter RecyclerView设置滚动事件加入上拉加载setOnScrollListener RecyclerView加入FootView实现上拉加载布局状态标志getItemCount()getItemViewTypeonCreateViewHolderonBindViewHolderRefreshFoot AdaptersetOnScrollListener SwipeRefreshLayout 、RecyclerView冲突下拉冲突的解决方案RecyclerView与ScrollView滑动冲突问题实现原理解决滑动冲突需要知道view传递

SwipeRefrshLayout

Google官方更新的一个Widget,可以实现下拉刷新的效果。

setOnRefreshListener(OnRefreshListener):添加下拉刷新监听器 setRefreshing(boolean):显示或者隐藏刷新进度条 isRefreshing():检查是否处于刷新状态 setColorSchemeResources():设置进度条的颜色主题,最多设置四种,以前的setColorScheme()方法已经弃用了。

RecyclerView+SwpieRefreshLayout实现下拉刷新效果 布局文件 onRefresh()

在Activity中获取SwipeRefreshLayout控件并且设置OnRefreshListener监听器,同时实现里边的onRefresh()方法,在该方法中进行网络请求最新数据,然后刷新RecyclerView列表同时设置SwipeRefreshLayout的进度Bar的隐藏或者显示效果。

demo_swiperefreshlayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { Log.d("zttjiangqq","invoke onRefresh..."); new Handler().postDelayed(newRunnable() { @Override public void run() { List newDatas = new ArrayList(); for (int i = 0; i private LayoutInflater mInflater; private List mTitles=null; public RefreshRecyclerAdapter(Context context){ this.mInflater=LayoutInflater.from(context); this.mTitles=new ArrayList(); for (int i=0;i final Viewview=mInflater.inflate(R.layout.item_recycler_layout,parent,false); //这边可以做一些属性设置,甚至事件监听绑定 //view.setBackgroundColor(Color.RED); ViewHolder viewHolder=new ViewHolder(view); return viewHolder; } /** * 数据的绑定显示 * @param holder * @param position */ @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.item_tv.setText(mTitles.get(position)); holder.itemView.setTag(position); } @Override public int getItemCount() { return mTitles.size(); } //自定义的ViewHolder,持有每个Item的的所有界面元素 public static class ViewHolder extends RecyclerView.ViewHolder { public TextView item_tv; public ViewHolder(View view){ super(view); item_tv = (TextView)view.findViewById(R.id.item_tv); } } //添加数据 public void addItem(List newDatas) { //mTitles.add(position, data); //notifyItemInserted(position); newDatas.addAll(mTitles); mTitles.removeAll(mTitles); mTitles.addAll(newDatas); notifyDataSetChanged(); } public void addMoreItem(List newDatas) { mTitles.addAll(newDatas); notifyDataSetChanged(); } } RecyclerView设置滚动事件加入上拉加载

LayoutManger给我们提供了以下几个方法来让开发者方便的获取到屏幕上面的顶部item和顶部item相关的信息: findFirstVisibleItemPosition() findFirstCompletlyVisibleItemPosition() findLastVisibleItemPosition() findLastCompletlyVisibleItemPosition()

setOnScrollListener

通过监听滑动(滚动)事件,然后在里边判断是否已经滑动到最底部来加载更多的数据

//RecyclerView滑动监听 demo_recycler.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState ==RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 ==adapter.getItemCount()) { new Handler().postDelayed(new Runnable() { @Override public void run() { List newDatas = new ArrayList(); for (int i = 0; i super.onScrolled(recyclerView,dx, dy); lastVisibleItem =linearLayoutManager.findLastVisibleItemPosition(); } }); RecyclerView加入FootView实现上拉加载

让用户知道确实在上拉加载的过程吧,例如加载一个底部的进度布局。这样一想,那么我们就按照ListView方式addFootView()呗,不过很可惜的是RecyclerView没有给我们提供addFootView(),有一个getItemViewType()返回是普通item还是底部刷新item

布局状态标志

加入布局状态标志-用来判断此时加载是普通Item还是foot view:

private static final int TYPE_ITEM =0; // 普通Item View private static final intTYPE_FOOTER = 1; // 底部FootView getItemCount()

重写getItemCount()方法,返回的Item数量在数据的基础上面+1,增加一项FootView布局项

public int getItemCount() { return mTitles.size()+1; } getItemViewType public int getItemViewType(int position) { // 最后一个item设置为footerView if (position + 1 == getItemCount()) { return TYPE_FOOTER; } else { return TYPE_ITEM; } } onCreateViewHolder public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //进行判断显示类型,来创建返回不同的View if(viewType==TYPE_ITEM){ Viewview=mInflater.inflate(R.layout.item_recycler_layout,parent,false); //这边可以做一些属性设置,甚至事件监听绑定 //view.setBackgroundColor(Color.RED); ItemViewHolder itemViewHolder=new ItemViewHolder(view); return itemViewHolder; }else if(viewType==TYPE_FOOTER){ Viewfoot_view=mInflater.inflate(R.layout.recycler_load_more_layout,parent,false); //这边可以做一些属性设置,甚至事件监听绑定 //view.setBackgroundColor(Color.RED); FootViewHolder footViewHolder=new FootViewHolder(foot_view); return footViewHolder; } return null; } onBindViewHolder public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if(holder instanceof ItemViewHolder) { ((ItemViewHolder)holder).item_tv.setText(mTitles.get(position)); holder.itemView.setTag(position); }else if(holder instanceof FootViewHolder){ FootViewHolderfootViewHolder=(FootViewHolder)holder; switch (load_more_status){ case PULLUP_LOAD_MORE: footViewHolder.foot_view_item_tv.setText("上拉加载更多..."); break; case LOADING_MORE: footViewHolder.foot_view_item_tv.setText("正在加载更多数据..."); break; } } } RefreshFoot Adapter packagecom.chinaztt.fda.adapter; public class RefreshFootAdapter extends RecyclerView.Adapter{ //上拉加载更多 public static final int PULLUP_LOAD_MORE=0; //正在加载中 public static final int LOADING_MORE=1; //上拉加载更多状态-默认为0 private int load_more_status=0; private LayoutInflater mInflater; private List mTitles=null; private static final intTYPE_ITEM = 0; //普通Item View private static final intTYPE_FOOTER = 1; //顶部FootView public RefreshFootAdapter(Context context){ this.mInflater=LayoutInflater.from(context); this.mTitles=new ArrayList(); for (int i=0;i //进行判断显示类型,来创建返回不同的View if(viewType==TYPE_ITEM){ Viewview=mInflater.inflate(R.layout.item_recycler_layout,parent,false); //这边可以做一些属性设置,甚至事件监听绑定 //view.setBackgroundColor(Color.RED); ItemViewHolder itemViewHolder=new ItemViewHolder(view); return itemViewHolder; }else if(viewType==TYPE_FOOTER){ Viewfoot_view=mInflater.inflate(R.layout.recycler_load_more_layout,parent,false); //这边可以做一些属性设置,甚至事件监听绑定 //view.setBackgroundColor(Color.RED); FootViewHolder footViewHolder=new FootViewHolder(foot_view); return footViewHolder; } return null; } /** * 数据的绑定显示 * @param holder * @param position */ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if(holder instanceof ItemViewHolder) { ((ItemViewHolder)holder).item_tv.setText(mTitles.get(position)); holder.itemView.setTag(position); }else if(holder instanceof FootViewHolder){ FootViewHolder footViewHolder=(FootViewHolder)holder; switch (load_more_status){ case PULLUP_LOAD_MORE: footViewHolder.foot_view_item_tv.setText("上拉加载更多..."); break; case LOADING_MORE: footViewHolder.foot_view_item_tv.setText("正在加载更多数据..."); break; } } } /** * 进行判断是普通Item视图还是FootView视图 * @param position * @return */ @Override public int getItemViewType(int position) { // 最后一个item设置为footerView if (position + 1 == getItemCount()) { return TYPE_FOOTER; } else { return TYPE_ITEM; } } @Override public int getItemCount() { return mTitles.size()+1; } //自定义的ViewHolder,持有每个Item的的所有界面元素 public static class ItemViewHolder extends RecyclerView.ViewHolder { public TextView item_tv; public ItemViewHolder(View view){ super(view); item_tv = (TextView)view.findViewById(R.id.item_tv); } } /** * 底部FootView布局 */ public static class FootViewHolder extends RecyclerView.ViewHolder{ private TextView foot_view_item_tv; public FootViewHolder(View view) { super(view); foot_view_item_tv=(TextView)view.findViewById(R.id.foot_view_item_tv); } } //添加数据 public void addItem(List newDatas) { //mTitles.add(position, data); //notifyItemInserted(position); newDatas.addAll(mTitles); mTitles.removeAll(mTitles); mTitles.addAll(newDatas); notifyDataSetChanged(); } public void addMoreItem(List newDatas) { mTitles.addAll(newDatas); notifyDataSetChanged(); } /** * //上拉加载更多 * PULLUP_LOAD_MORE=0; * //正在加载中 * LOADING_MORE=1; * //加载完成已经没有更多数据了 * NO_MORE_DATA=2; * @param status */ public void changeMoreStatus(int status){ load_more_status=status; notifyDataSetChanged(); } } setOnScrollListener

Adaper中我还定义一个changeMoreStatus()方法和两个字符串常量可以来进行修改FootView中字符串提醒文本的。 整体Activity中还是设置监听RecyclerView的滚动事件.

demo_recycler.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState ==RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 ==adapter.getItemCount()) { adapter.changeMoreStatus(RefreshFootAdapter.LOADING_MORE); newHandler().postDelayed(new Runnable() { @Override public void run() { List newDatas = new ArrayList(); for (int i = 0; i super.onScrolled(recyclerView,dx, dy); lastVisibleItem =linearLayoutManager.findLastVisibleItemPosition(); } }); SwipeRefreshLayout 、RecyclerView冲突下拉冲突的解决方案

出现RecyclerView没有滑动到顶部,手指向下滑动时,触发了SwipeRefreshLayout的刷新事件,造成了冲突。

recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener(){ @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { int topRowVerticalPosition = (recyclerView == null || recyclerView.getChildCount() == 0) ? 0 : recyclerView.getChildAt(0).getTop(); swipeRefreshLayout.setEnabled(topRowVerticalPosition >= 0); } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); } }); RecyclerView与ScrollView滑动冲突问题

参考文章: 【Android 手势冲突】Colin带你彻底解决RecyclerView与ScrollView滑动冲突问题,并实现RecyclerView悬停导航栏(附demo哦)

实现原理

在进到页面中默认把滑动事件交给ScrollView,同时屏蔽RecyclerView的滑动事件;在RecyclerView滑动到顶部的时候,把滑动事件交给RecyclerView。 判断RecyclerView是否滑动到了屏幕顶部了呢?通过recyclerview的getTop方法得到recyclerview距离顶部的距离,然后通过scrollView的getScrollY方法得到ScrollView滑动的距离,只需要比较这两个值。

解决滑动冲突需要知道view传递

如何把事件传给内部View? 只需要在ScrollView滑动到某个位置后 getScrollY() >= recyclerView.getChildAt(0).getTop(); 使用接口回调,并且让RecyclerView在接口回调里,getParent().requestdisallowintercept()。

RecyclerView如何把事件传给外部? 需要给RecyclerView设置ontouchlistener,然后在RecyclerView滑动到第一个item recyclerView.getChildAt(0).getTop() case MotionEvent.ACTION_DOWN: //必须返回false,否则子控件永远无法拿到焦点 return false; case MotionEvent.ACTION_MOVE: if(事件交给子控件的条件) { return false; } else { return super.onInterceptTouchEvent(ev); } case MotionEvent.ACTION_UP: //必须返回false,否则子控件永远无法拿到焦点 return false; default: return super.onInterceptTouchEvent(ev); } }

内部拦截法

@Override public boolean dispatchTouchEvent(MotionEvent ev) { switch(ev.getAction()) { case MotionEvent.ACTION_DOWN: //父容器禁止拦截 getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_MOVE: if(事件交给父容器的条件) { getParent().requestDisallowInterceptTouchEvent(false); } break; case MotionEvent.ACTION_UP: break; default: break; } return super.dispatchTouchEvent(ev); }


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭