SwipeRefreshLayout+RecyclerView 实现上拉追加功能
2016-03-09 18:13
369 查看
参考连接1:http://blog.csdn.net/bboyfeiyu/article/details/39935329
直奔主题,按照上面参考链接确实是满足需求,但RecyclerView作为一个比ListView更灵活的一个控件,完全取代ListView只是时间的问题。所以这篇博文是记录我自己的实现方法。
首先是RecyclerView增加上拉的时候 加载中的view动画,可以沿用上面参考链接的listview_footer.xml
在ListView中 我们可以用addHeaderView或者addFooterView添加头尾,但RecyclerView并没有这个功能,网上参考是改写RecyclerViewAdapter
在返回FooterViewHolder的时候,有一句view.setVisibility(View.GONE); 稍候解释为什么怎么做。
在getItemCount()+1是为了FooterViewHolder预留一个view的位置,到此RecyclerView的改写基本完成,往下就是重点了
/////////////////////////////////////////喝口茶的分割线/////////////////////////////////////////
RefreshLayout中,首先肯定是要把getChildView的ListView改成RecyclerView,其中也要替换onScrolled的监听吧。这些就不详细论述了,直接上改变后的代码
第二个变化点,判断是否到了最底部函数isBottom;其中我们必须知道RecyclerView是有横 纵 瀑布等LayoutManager的,我们要恰当的分开处理。
好了,离完工就差最后一步了,就是setLoading(true/false),我觉得参考链接的博主暴露这个接口真的设计得非常好,完全和原生的swipeRefreshLayout下拉刷新媲美。
也是废话不说,上更改后的代码
来到这里大家应该都明白了之前,在onCreateViewHolder返回FooterViewHolder的时候,有一句view.setVisibility(View.GONE)吧,其实那个加载动画一直都在整个RecyclerView的底部,我只是在恰当的时间隐藏/展示它罢了。
但这里大家必须注意的就是,此时的RecyclerView的itemsize永远是比你实际数据多1的,这点请大家注意!!!重要的话只说一遍。
至于demo,基本上可参照原参考链接的,这里也分享一下近日自己做的一个记账app,简单粗暴。
https://github.com/MrZhaozhirong/MyBill
直奔主题,按照上面参考链接确实是满足需求,但RecyclerView作为一个比ListView更灵活的一个控件,完全取代ListView只是时间的问题。所以这篇博文是记录我自己的实现方法。
首先是RecyclerView增加上拉的时候 加载中的view动画,可以沿用上面参考链接的listview_footer.xml
在ListView中 我们可以用addHeaderView或者addFooterView添加头尾,但RecyclerView并没有这个功能,网上参考是改写RecyclerViewAdapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<ViewHolder> { private static final int TYPE_ITEM = 0; private static final int TYPE_FOOTER = 1; private Context mContext; private List<listItemBean> mItemsList; public RecyclerViewAdapter(Context context, List<listItemBean> itemsList) { mContext=context; mItemsList = itemsList; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == TYPE_ITEM) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_list_item,parent,false); return new ItemViewHolder(view); } else if (viewType == TYPE_FOOTER) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_footer,parent,false); view.setVisibility(View.GONE); return new FooterViewHolder(view); } return null; } @Override public void onBindViewHolder(ViewHolder holder, int position) { if (holder instanceof ItemViewHolder) { listItemBean itemBean = mItemsList.get(position); ((ItemViewHolder)holder).mDetailTextView.setText(itemBean.getDetailText()); ((ItemViewHolder)holder).mMainTextView.setText(itemBean.getMainText()); } } @Override public int getItemCount() { return mItemsList.size()+1; //return mItemsList.size(); } @Override public int getItemViewType(int position) { if (position+1 == getItemCount()) { return TYPE_FOOTER; } else { return TYPE_ITEM; } } class ItemViewHolder extends RecyclerView.ViewHolder { public final TextView mMainTextView; public final TextView mDetailTextView; public ItemViewHolder(View itemView) { super(itemView); mMainTextView = (TextView) itemView.findViewById(R.id.tv_main); mDetailTextView= (TextView) itemView.findViewById(R.id.tv_detail); } } class FooterViewHolder extends RecyclerView.ViewHolder{ public final ProgressBar progressBar; public final TextView loadingTips; public FooterViewHolder(View view) { super(view); progressBar = (ProgressBar) view.findViewById(R.id.pull_to_refresh_load_progress); loadingTips = (TextView) view.findViewById(R.id.pull_to_refresh_loading_text); } } }
在返回FooterViewHolder的时候,有一句view.setVisibility(View.GONE); 稍候解释为什么怎么做。
在getItemCount()+1是为了FooterViewHolder预留一个view的位置,到此RecyclerView的改写基本完成,往下就是重点了
/////////////////////////////////////////喝口茶的分割线/////////////////////////////////////////
RefreshLayout中,首先肯定是要把getChildView的ListView改成RecyclerView,其中也要替换onScrolled的监听吧。这些就不详细论述了,直接上改变后的代码
private void getChildView() { int childs = getChildCount(); if (childs > 0) { View childView = getChildAt(0); if (childView instanceof RecyclerView) { mRecyclerView = (RecyclerView) childView; // 设置滚动监听器给RecyclerView, 使得滚动的情况下也可以自动加载 mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { // 滚动时到了最底部也可以加载更多 if (canLoad()) { loadData(); } } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); } }); Log.d(TAG, "### 找到RecyclerView"); } } }
第二个变化点,判断是否到了最底部函数isBottom;其中我们必须知道RecyclerView是有横 纵 瀑布等LayoutManager的,我们要恰当的分开处理。
/*判断是否到了最底部*/ private boolean isBottom() { RecyclerView.LayoutManager layoutManager = null; if (mRecyclerView != null) { layoutManager = mRecyclerView.getLayoutManager(); }else{ return false; } if(layoutManager instanceof LinearLayoutManager){ LinearLayoutManager lm = (LinearLayoutManager) mRecyclerView.getLayoutManager(); int position = lm.findLastVisibleItemPosition(); int itemCount = lm.getItemCount(); Log.d(TAG,"current position:"+position); Log.d(TAG,"itemCount:"+itemCount); if(position+1 == lm.getItemCount() && lm.findViewByPosition(position).getBottom() <= getHeight()){ Log.d(TAG, "RefreshLayout 滑动到底部了"); return true; } }else if(layoutManager instanceof StaggeredGridLayoutManager){ // http://www.imooc.com/qadetail/91200 Log.d(TAG, "layoutManager instanceof StaggeredGridLayoutManager not yet implemented"); Log.d(TAG, "RefreshLayout 滑动到底部了"); } return false; }
好了,离完工就差最后一步了,就是setLoading(true/false),我觉得参考链接的博主暴露这个接口真的设计得非常好,完全和原生的swipeRefreshLayout下拉刷新媲美。
也是废话不说,上更改后的代码
public void setLoading(boolean loading) { isLoading = loading; LinearLayoutManager lm = (LinearLayoutManager) mRecyclerView.getLayoutManager(); int position = lm.findLastVisibleItemPosition(); // int itemCount = mRecyclerView.getLayoutManager().getItemCount(); // int childCount = mRecyclerView.getLayoutManager().getChildCount(); // Log.d(TAG,"getChildCount:"+childCount); // Log.d(TAG,"getItemCount:"+itemCount); View lastView = lm.findViewByPosition(position); if (isLoading) { lastView.setVisibility(View.VISIBLE); } else { lastView.setVisibility(View.GONE); mDownY = 0; mLastY = 0; } }
来到这里大家应该都明白了之前,在onCreateViewHolder返回FooterViewHolder的时候,有一句view.setVisibility(View.GONE)吧,其实那个加载动画一直都在整个RecyclerView的底部,我只是在恰当的时间隐藏/展示它罢了。
但这里大家必须注意的就是,此时的RecyclerView的itemsize永远是比你实际数据多1的,这点请大家注意!!!重要的话只说一遍。
至于demo,基本上可参照原参考链接的,这里也分享一下近日自己做的一个记账app,简单粗暴。
https://github.com/MrZhaozhirong/MyBill
相关文章推荐
- Struts2的简单认识
- Robotium入门
- HDU-1072-Nightmare
- Android系统Recovery工作原理之使用update.zip升级过程分析(三)---Android系统的三种启动模式
- 蓝桥杯 基础练习 十六进制转八进制
- pipework源码分析
- 一起看代码来玩玩QT之22 VideoPlayer (linux 下 )
- CSS权威指南 笔记
- 第一周项目1—宣告主权
- TabLayout+Fragment+ViewPager联合使用
- 《我是一只IT小小鸟》读后感
- 关于印象笔记的扫描宝——简单的图像背景去除(去底色)算法小结
- java学习之自定义异常
- HBase纪要
- 一次sql排序的问题。
- jquery checkbox checked
- [LeetCode][JavaScript]Find Minimum in Rotated Sorted Array II
- 深入解析设计模式中的适配器模式在C++中的运用
- java中类序列化与反序列化的实现
- js注意事项