RecyclerView实现瀑布流遇到的各种问题(item移动,加载更多图片闪烁,以及定制各种类型Header和Footer)
2016-06-06 17:04
781 查看
功能:图片瀑布流
问题1:如何保持已显示过的imageview的尺寸
解决方法:定义一个HashMap<Integer, Float> indexMap = new HashMap<Integer, Float>();用来保存已显示过的ImageView尺寸,显示时直接取其比例即可
代码:onBindItemView(),调用resizeItemView(itemViewHolder.frontCoverImage, getScaleType(position));
以上解决了滑动过程中的item移动,但是RecyclerView滑动到顶部时仍会出现移动问题,这是由于item重用,并且要保持满屏造成的
问题2:RecyclerView滑动到顶部时仍会出现移动问题
解决方法:
以上解决了item移动的各种问题
问题3:瀑布流加载更多用notifyDataSetChanged()刷新图片闪烁
原因:notifyDataSetChanged()会导致整个itemview刷新,已经测试:相同position刷新其itemview是不同的对象,例如,刷新后,position为12的用了position为13的itemview,再次刷新时,又用了position为10的itemview,这样次position上对应的itemview的ImageView就会在重设size时发生闪烁,此现象是可以用肉眼看到的。
解决方法:
用notifyItemRangeInserted()进行局部刷新,这样原先的itemview就不会重绘
问题1:如何保持已显示过的imageview的尺寸
解决方法:定义一个HashMap<Integer, Float> indexMap = new HashMap<Integer, Float>();用来保存已显示过的ImageView尺寸,显示时直接取其比例即可
代码:onBindItemView(),调用resizeItemView(itemViewHolder.frontCoverImage, getScaleType(position));
private float getScaleType(int position) { if (!indexMap.containsKey(position)) { float scaleType; if (hasHeader()) { if (position == 1) { scaleType = SIZE_SCALE_01; } else if (position == 2) { scaleType = SIZE_SCALE_02; } else { scaleType = Utils.getRandomInt() % 2 == 0 ? SIZE_SCALE_01 : SIZE_SCALE_02; } } else { if (position == 0) { scaleType = SIZE_SCALE_01; } else if (position == 1) { scaleType = SIZE_SCALE_02; } else { scaleType = Utils.getRandomInt() % 2 == 0 ? SIZE_SCALE_01 : SIZE_SCALE_02; } } indexMap.put(position, scaleType); } return indexMap.get(position); } private void resizeItemView(ImageView frontCoverImage, float scaleType) { LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) frontCoverImage.getLayoutParams(); params.width = screenWidth / 2; params.height = (int) (params.width / scaleType) - Utils.dp2px(context, 8); frontCoverImage.setLayoutParams(params); }<pre name="code" class="java">private void resizeItemView(ImageView frontCoverImage, float scaleType) { LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) frontCoverImage.getLayoutParams(); params.width = screenWidth / 2; params.height = (int) (params.width / scaleType) - Utils.dp2px(context, 8); frontCoverImage.setLayoutParams(params); }
以上解决了滑动过程中的item移动,但是RecyclerView滑动到顶部时仍会出现移动问题,这是由于item重用,并且要保持满屏造成的
问题2:RecyclerView滑动到顶部时仍会出现移动问题
解决方法:
final StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); //RecyclerView滑动过程中不断请求layout的Request,不断调整item见的间隙,并且是在item尺寸显示前预处理,因此解决RecyclerView滑动到顶部时仍会出现移动问题 layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE); mRecyclerView.setLayoutManager(layoutManager); mRecyclerView.addItemDecoration(new DividerGridItemDecoration(getContext())); mRecyclerView.setPadding(0, 0, 0, 0); mRecyclerView.addOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); layoutManager.invalidateSpanAssignments(); } });
以上解决了item移动的各种问题
问题3:瀑布流加载更多用notifyDataSetChanged()刷新图片闪烁
原因:notifyDataSetChanged()会导致整个itemview刷新,已经测试:相同position刷新其itemview是不同的对象,例如,刷新后,position为12的用了position为13的itemview,再次刷新时,又用了position为10的itemview,这样次position上对应的itemview的ImageView就会在重设size时发生闪烁,此现象是可以用肉眼看到的。
解决方法:
用notifyItemRangeInserted()进行局部刷新,这样原先的itemview就不会重绘
相关文章推荐
- 在 Linux 中如何移动文件
- PowerShell移动目录中指定文件的方法(非全部文件)
- 鼠标触发移动的分层菜单 层菜单moveMenu
- 基于Android实现随手指移动的ImageView
- php实现复制移动文件的方法
- javascript实现图片跟随鼠标移动效果的方法
- JavaScript Select和Option列表元素上下左右移动
- JavaScript代码实现左右上下自动晃动自动移动
- JS实现网页游戏中滑块响应鼠标点击移动效果
- JS+CSS实现分类动态选择及移动功能效果代码
- 详解jQuery移动页面开发中的ui-grid网格布局使用
- jquery移动点击的项目到列表最顶端的方法
- 基于jquery实现select选择框内容左右移动添加删除代码分享
- jquery实现select选择框内容左右移动代码分享
- 使用jQuery mobile库检测url绝对地址和相对地址的方法
- jQuery移动web开发之页面跳转和加载外部页面的实现
- JQuery移动页面开发之屏幕方向改变与滚屏的实现
- 浅析jQuery Mobile的初始化事件
- C#中无边框窗体移动的简单实例
- c#文件的复制,移动,创建(实例代码)