RecyclerView上拉刷新,下拉加载更多
来源:互联网 发布:淘宝衣服质量好的店铺 编辑:程序博客网 时间:2024/05/22 15:25
RecyclerView上拉刷新,下拉加载更多
经常在写项目的时候都会碰到RecyclerView上拉刷新,下拉加载更多的功能,今天自己来捋一捋。
效果图
下拉刷新(SwipeRefreshLayout)
这是Google自己出的下拉刷新控件,其实还挺好看的,这里我们只要知道其中几个方法就可以了。
1. setColorSchemeResources
2. setOnRefreshListener
第一个是设置刷新时小圆圈的颜色,可以设置4中颜色切换。
第二个方法是设置刷新监听。这个接口里面有个onRefresh方法,刷新任务就在这里面执行。
所以总而言之下拉刷新才用官方的还是so easy.
在刷新任务完成后,你就可以把新数注入到adapter里面,刷新下就可以完成下拉刷新。
上拉加载更多
首先需要判断是否滑动到底部了,所以写个抽象类,继承RecyclerView的OnScrollListener
public abstract class RecyclerOnScrollListener extends RecyclerView.OnScrollListener { private int mPreviousTotal = 0; private boolean mLoading = true; int mFirstVisibleItem, mVisibleItemCount, mTotalItemCount;//第一个item,显示的item总数,整个item总数 private int currentPage = 1; private LinearLayoutManager mLinearLayoutManager; public RecyclerOnScrollListener( LinearLayoutManager linearLayoutManager) { this.mLinearLayoutManager = linearLayoutManager; } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); mVisibleItemCount = recyclerView.getChildCount(); mTotalItemCount = mLinearLayoutManager.getItemCount(); mFirstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition(); if (mLoading) { if (mTotalItemCount > mPreviousTotal) { mLoading = false; mPreviousTotal = mTotalItemCount; } } if (!mLoading && (mTotalItemCount - mVisibleItemCount) <= mFirstVisibleItem) { currentPage++; onLoadMore(currentPage); mLoading = true; } } public abstract void onLoadMore(int currentPage);}
这个类主要是判断是否滚动到了底部,滚动到了底部就去执行加载更多方法
添加底部加载更多布局
因为加载更多是属于耗时操作,为了提高用户体验,所以很有必要加个进度条提示。
进度条可以当做为一个item,在滑动到最后的时候就让他显示出来。
这里我采用了牛人的一个类,来辅助我们实现这个效果。站在巨人的肩膀上就可以看得更远。
到时直接把自己的适配器传递进去就行了。先贴上大神的代码
public class HeaderViewRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private static final int HEADERS_START = Integer.MIN_VALUE; private static final int FOOTERS_START = Integer.MIN_VALUE + 10; private static final int ITEMS_START = Integer.MIN_VALUE + 20; private static final int ADAPTER_MAX_TYPES = 100; private RecyclerView.Adapter mWrappedAdapter; private List<View> mHeaderViews, mFooterViews; private Map<Class, Integer> mItemTypesOffset; /** * Construct a new header view recycler adapter * @param adapter The underlying adapter to wrap */ public HeaderViewRecyclerAdapter(RecyclerView.Adapter adapter) { mHeaderViews = new ArrayList<View>(); mFooterViews = new ArrayList<View>(); mItemTypesOffset = new HashMap<Class, Integer>(); setWrappedAdapter(adapter); } /** * Replaces the underlying adapter, notifying RecyclerView of changes * @param adapter The new adapter to wrap */ public void setAdapter(RecyclerView.Adapter adapter) { if(mWrappedAdapter != null && mWrappedAdapter.getItemCount() > 0) { notifyItemRangeRemoved(getHeaderCount(), mWrappedAdapter.getItemCount()); } setWrappedAdapter(adapter); notifyItemRangeInserted(getHeaderCount(), mWrappedAdapter.getItemCount()); } @Override public int getItemViewType(int position) { int hCount = getHeaderCount(); if (position < hCount) return HEADERS_START + position; else { int itemCount = mWrappedAdapter.getItemCount(); if (position < hCount + itemCount) { return getAdapterTypeOffset() + mWrappedAdapter.getItemViewType(position - hCount); } else return FOOTERS_START + position - hCount - itemCount; } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { if (viewType < HEADERS_START + getHeaderCount()) return new StaticViewHolder(mHeaderViews.get(viewType - HEADERS_START)); else if (viewType < FOOTERS_START + getFooterCount()) return new StaticViewHolder(mFooterViews.get(viewType - FOOTERS_START)); else { return mWrappedAdapter.onCreateViewHolder(viewGroup, viewType - getAdapterTypeOffset()); } } @Override public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { int hCount = getHeaderCount(); if (position >= hCount && position < hCount + mWrappedAdapter.getItemCount()) mWrappedAdapter.onBindViewHolder(viewHolder, position - hCount); } /** * Add a static view to appear at the start of the RecyclerView. Headers are displayed in the * order they were added. * @param view The header view to add */ public void addHeaderView(View view) { mHeaderViews.add(view); } /** * Add a static view to appear at the end of the RecyclerView. Footers are displayed in the * order they were added. * @param view The footer view to add */ public void addFooterView(View view) { mFooterViews.add(view); } @Override public int getItemCount() { return getHeaderCount() + getFooterCount() + getWrappedItemCount(); } /** * @return The item count in the underlying adapter */ public int getWrappedItemCount() { return mWrappedAdapter.getItemCount(); } /** * @return The number of header views added */ public int getHeaderCount() { return mHeaderViews.size(); } /** * @return The number of footer views added */ public int getFooterCount() { return mFooterViews.size(); } private void setWrappedAdapter(RecyclerView.Adapter adapter) { if (mWrappedAdapter != null) mWrappedAdapter.unregisterAdapterDataObserver(mDataObserver); mWrappedAdapter = adapter; Class adapterClass = mWrappedAdapter.getClass(); if(!mItemTypesOffset.containsKey(adapterClass)) putAdapterTypeOffset(adapterClass); mWrappedAdapter.registerAdapterDataObserver(mDataObserver); } private void putAdapterTypeOffset(Class adapterClass) { mItemTypesOffset.put(adapterClass, ITEMS_START + mItemTypesOffset.size() * ADAPTER_MAX_TYPES); } private int getAdapterTypeOffset() { return mItemTypesOffset.get(mWrappedAdapter.getClass()); } private RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() { @Override public void onChanged() { super.onChanged(); notifyDataSetChanged(); } @Override public void onItemRangeChanged(int positionStart, int itemCount) { super.onItemRangeChanged(positionStart, itemCount); notifyItemRangeChanged(positionStart + getHeaderCount(), itemCount); } @Override public void onItemRangeInserted(int positionStart, int itemCount) { super.onItemRangeInserted(positionStart, itemCount); notifyItemRangeInserted(positionStart + getHeaderCount(), itemCount); } @Override public void onItemRangeRemoved(int positionStart, int itemCount) { super.onItemRangeRemoved(positionStart, itemCount); notifyItemRangeRemoved(positionStart + getHeaderCount(), itemCount); } @Override public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { super.onItemRangeMoved(fromPosition, toPosition, itemCount); int hCount = getHeaderCount(); // TODO: No notifyItemRangeMoved method? notifyItemRangeChanged(fromPosition + hCount, toPosition + hCount + itemCount); } }; private static class StaticViewHolder extends RecyclerView.ViewHolder { public StaticViewHolder(View itemView) { super(itemView); } }}
这个类很好用,可以随意添加头和尾。它的主要原理也就是先获取源数据的item数,然后根据你添加的布局类型(头或者尾)去动态的添加到recyclerview里面。
最后贴上activity源代码吧,看看如何使用
public class MainActivity extends AppCompatActivity implements SwipeRefreshLayout.OnRefreshListener { private SwipeRefreshLayout mRefreshLayout; private RecyclerView mRecyclerView; private MyAdapter mAdapter; private List<String> mLists; private HeaderViewRecyclerAdapter mHeaderAdapter; private List<String> list=new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRefreshLayout= (SwipeRefreshLayout) findViewById(R.id.refreshlayout); mRecyclerView= (RecyclerView) findViewById(R.id.recyclerview); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能 mRecyclerView.setHasFixedSize(true); mRecyclerView.setLayoutManager(linearLayoutManager); mRefreshLayout.setColorSchemeResources( R.color.colorAccent, R.color.colorPrimary, R.color.read, R.color.blue ); mRefreshLayout.setOnRefreshListener(this); initdata(); mAdapter=new MyAdapter(MainActivity.this,mLists); mHeaderAdapter=new HeaderViewRecyclerAdapter(mAdapter); mRecyclerView.setAdapter(mHeaderAdapter); initFootView(); mRecyclerView.addOnScrollListener(new RecyclerOnScrollListener(linearLayoutManager) { @Override public void onLoadMore(int currentPage) { loadMoreData(); } }); } private void initFootView() { View loadMoreView = LayoutInflater .from(MainActivity.this) .inflate(R.layout.item_foot_layout, mRecyclerView, false); mHeaderAdapter.addFooterView(loadMoreView); } private void initdata() { mLists=new ArrayList<>(); for (int i=0;i<15;i++){ mLists.add(""+i+" itme"); } } /** * 测试数据,延迟两秒执行 */ private void loadMoreData(){ Handler handler=new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { loadData(); } },2000); } private void loadData(){ list.clear(); for (int i=0;i<5;i++){ list.add("上拉加载出来的数据"); } mLists.addAll(list); mHeaderAdapter.notifyDataSetChanged(); } @Override public void onRefresh() { Handler handler=new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { mRefreshLayout.setRefreshing(false); Toast.makeText(MainActivity.this,"数据刷新了",Toast.LENGTH_SHORT).show(); } },2000); }}
这里数据都是测试数据,实际上可以根据自己需求去获取的,获取完后添加到原数据里面,然后刷新一下就OK了(这里先不用考虑局部刷新……)。
0 0
- RecyclerView 下拉刷新上拉加载更多
- RecyclerView 下拉刷新上拉加载更多
- RecyclerView 下拉刷新、上拉加载更多
- RecyclerView 下拉刷新上拉加载更多
- RecyclerView上拉刷新,下拉加载更多
- RecyclerView 下拉刷新上拉加载更多
- RecyclerView上拉加载更多,下拉刷新
- Android中RecyclerView实现下拉刷新上拉加载更多
- RecyclerView实现下拉刷新上拉加载更多
- RecyclerView实现下拉刷新和上拉加载更多
- RecyclerView 增加下拉刷新,上拉加载更多功能分析
- 封装RecyclerViewAdapter实现RecyclerView下拉刷新上拉加载更多
- 可以下拉刷新,上拉加载更多的RecyclerView
- recyclerview+swiperefreshlayout实现GridView下拉刷新,上拉加载更多
- RecyclerView 上拉加载更多以及下拉刷新
- SwipeRefreshLayout配合RecyclerView实现上拉加载更多下拉刷新
- YRecyclerView自定义下拉刷新上拉加载更多的RecyclerView
- SwipeRefreshLayout + RecyclerView下拉刷新,上拉加载更多
- 2016年12月15日学习总结----阶段总结
- 解决centos中"ImportError: No module named _tkinter"问题
- 用VS2005编译Qt4.6.3过程记录
- html+css书店
- 第一单元作业
- RecyclerView上拉刷新,下拉加载更多
- Android Studio编译项目 9 patch图片报错
- #if、#ifdef、#if defined之间的区别
- 222. Count Complete Tree Nodes
- 线程编程补充
- 将字符串(border-bottom-color)转成驼峰(borderBottomColor)
- Full Stack Web Development Bootstrap(四)学习笔记
- 集成电路发展历史(国外与国内)大事记
- DrawerLayout实现侧滑(一)