RecyclerView添加头部和尾部并解决no
来源:互联网 发布:ubuntu 16.04默认字体 编辑:程序博客网 时间:2024/05/16 04:24
原理:封装基类RecyclerView.Adapter,名字为WrapAdapter;功能性的Adapter名字叫RealAdapter;在WrapAdapter的回调中封装头和尾View,并且调用RealAdapter的相应回调。实现功能。
主要属性:
private final T mRealAdapter; private boolean isStaggeredGrid; private static final int BASE_HEADER_VIEW_TYPE = -1 << 10; private static final int BASE_FOOTER_VIEW_TYPE = -1 << 11; private ArrayList<FixedViewInfo> mHeaderViewInfos = new ArrayList<>(); private ArrayList<FixedViewInfo> mFooterViewInfos = new ArrayList<>();
主要功能:
1:添加头部和尾部
/** * Adds a header view * * @param view */ public void addHeaderView(View view) { if (null == view) { throw new IllegalArgumentException("the view to add must not be null!"); } final FixedViewInfo info = new FixedViewInfo(); info.view = view; info.viewType = BASE_HEADER_VIEW_TYPE + mHeaderViewInfos.size(); mHeaderViewInfos.add(info); notifyDataSetChanged(); } /** * Adds a footer view * * @param view */ public void addFooterView(View view, boolean reverse) { if (null == view) { throw new IllegalArgumentException("the view to add must not be null!"); } final FixedViewInfo info = new FixedViewInfo(); info.view = view; info.viewType = BASE_FOOTER_VIEW_TYPE + mFooterViewInfos.size(); mFooterViewInfos.add(info); if (reverse) { for (int i = 0; i < mFooterViewInfos.size(); i++) { FixedViewInfo fixedViewInfo = mFooterViewInfos.get(i); fixedViewInfo.viewType = BASE_FOOTER_VIEW_TYPE + mFooterViewInfos.size() - i - 1; } } notifyDataSetChanged(); }2:功能逻辑代码
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { if (isHeader(viewType)) { int whichHeader = Math.abs(viewType - BASE_HEADER_VIEW_TYPE); View headerView = mHeaderViewInfos.get(whichHeader).view; return createHeaderFooterViewHolder(headerView); } else if (isFooter(viewType)) { int whichFooter = Math.abs(viewType - BASE_FOOTER_VIEW_TYPE); View footerView = mFooterViewInfos.get(whichFooter).view; return createHeaderFooterViewHolder(footerView); } else { return mRealAdapter.onCreateViewHolder(viewGroup, viewType); } } private RecyclerView.ViewHolder createHeaderFooterViewHolder(View view) { if (isStaggeredGrid) { StaggeredGridLayoutManager.LayoutParams params = new StaggeredGridLayoutManager.LayoutParams( StaggeredGridLayoutManager.LayoutParams.MATCH_PARENT, StaggeredGridLayoutManager.LayoutParams.WRAP_CONTENT); params.setFullSpan(true); view.setLayoutParams(params); } return new RecyclerView.ViewHolder(view) { }; } @SuppressWarnings("unchecked") @Override public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { if (position < mHeaderViewInfos.size()) { // Headers don't need anything special } else if (position < mHeaderViewInfos.size() + mRealAdapter.getItemCount()) { // This is a real position, not a header or footer. Bind it. mRealAdapter.onBindViewHolder(viewHolder, position - mHeaderViewInfos.size()); } else { // Footers don't need anything special } } @Override public int getItemCount() { return mHeaderViewInfos.size() + mRealAdapter.getItemCount() + mFooterViewInfos.size(); } @Override public int getItemViewType(int position) { if (isHeaderPosition(position)) { return mHeaderViewInfos.get(position).viewType; } else if (isFooterPosition(position)) { return mFooterViewInfos.get(position - mHeaderViewInfos.size() - mRealAdapter.getItemCount()).viewType; } else { return mRealAdapter.getItemViewType(position - mHeaderViewInfos.size()); } }
这样就可以简介的实现RecylerView添加头部和尾部的功能。这样做会误导我们:比如我们notify时,都是用自己的adapter.nitify的,这样封装后,notify无效。以上代码参考于zwenkai的博客,地址:http://blog.csdn.net/xuehuayous/article/details/50498345;
这样做可以方便,简洁的实现RecylerView添加头部和尾部的功能,但是有一个问题:
当用自己写的adapter.notifyDataSetChanged()时,无效果。
因为setAdapter时用的时WrapAdapter,它成为了观察者。
源码:
原因:因为RecylerView设置adapter用的WrapAdapter,所以无效。你可以直接用WrapAdapter的对象notify。
如果想要用自己的adapter通知,则需要在注册称为被观察者,代码如下:
private RecyclerView.AdapterDataObserver mDataObserver = new RecyclerView.AdapterDataObserver() { @Override public void onChanged() { notifyDataSetChanged(); } @Override public void onItemRangeInserted(int positionStart, int itemCount) { notifyItemRangeInserted(positionStart, itemCount); } @Override public void onItemRangeChanged(int positionStart, int itemCount) { notifyItemRangeChanged(positionStart, itemCount); } @Override public void onItemRangeChanged(int positionStart, int itemCount, Object payload) { notifyItemRangeChanged(positionStart, itemCount, payload); } @Override public void onItemRangeRemoved(int positionStart, int itemCount) { notifyItemRangeRemoved(positionStart, itemCount); } @Override public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { notifyItemMoved(fromPosition, toPosition); } };
realAdapter.notify时,调用wrapAdaper的notify。
阅读全文
0 0
- RecyclerView添加头部和尾部并解决no
- RecyclerView添加头部和尾部
- RecyclerView添加头部和尾部
- RecyclerView添加头部尾部
- RecyclerView 添加头部和尾部布局
- Android RecyclerView添加头部和尾部
- RecyclerView 添加头部和尾部布局
- RecyclerView 添加头部和尾部布局
- 为RecyclerView添加头部和尾部
- Android RecyclerView添加头部和尾部
- recyclerview 添加头部和尾部的优雅
- Android 给RecyclerView添加头部和尾部
- RecyclerView 添加头部和尾部,并实现Item的点击事件
- RecyclerView 添加头部和尾部,并实现Item的点击事件
- (4.1.45.1)RecyclerView 添加头部和尾部布局 一
- RecyclerView学习(1) 添加头部和尾部
- RecyclerView LayoutManager分析 添加头部尾部
- 实战RecyclerView头部尾部添加方法
- ScheduledExecutorService
- SpringMVC之HandlerMethodArgumentResolver和<mvc:argument-resolvers>注解
- Maven里面mirror元素和repository元素的作用
- ubuntu终止进程的方法
- 百度地图SDK
- RecyclerView添加头部和尾部并解决no
- 端口的分类
- ffmpeg 源代码简单分析 : av_register_all()
- 域名管理与注册机制
- [BZOJ 1089][SCOI2003]严格n元树:DP+高精度
- Spring MVC 的常用注解
- String、StringBuffer与StringBuilder之间区别
- MySQL触发器使用详解
- 一个Restful Api的访问控制方法