ScrolView和RecyclerView嵌套使用的问题
来源:互联网 发布:java定义数组并赋值 编辑:程序博客网 时间:2024/06/09 17:11
我们的recyclerView有多个layoutmanager,通过重写layoutmanager的方法就可以让recyclerView和ScrollView嵌套了。但是请注意,如果recyclerView很长那么强烈不建议去做嵌套,因为这样recyclerView会在展示的时候立刻展示所有内容,效率极低。
本文的两部分代码来自一个博主的博客,另一个是我自己写的,正好可以完全适用于现有的layoutmanager。大家需要的话可以试试,应该问题不大。
原博主的demo:https://github.com/Frank-Zhu/AndroidRecyclerViewDemo
1.LinearLayoutManager和ScrollView嵌套
package com.frankzhu.recyclerviewdemo;import android.content.Context;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.util.Log;import android.view.View;import android.view.ViewGroup;/** * Author: ZhuWenWu * Version V1.0 * Date: 2015/2/26 14:15. * Description: * Modification History: * Date Author Version Description * ----------------------------------------------------------------------------------- * 2015/2/26 ZhuWenWu 1.0 1.0 * Why & What is modified: */public class FullyLinearLayoutManager extends LinearLayoutManager { private static final String TAG = FullyLinearLayoutManager.class.getSimpleName(); public FullyLinearLayoutManager(Context context) { super(context); } public FullyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) { super(context, orientation, reverseLayout); } private int[] mMeasuredDimension = new int[2]; @Override public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { final int widthMode = View.MeasureSpec.getMode(widthSpec); final int heightMode = View.MeasureSpec.getMode(heightSpec); final int widthSize = View.MeasureSpec.getSize(widthSpec); final int heightSize = View.MeasureSpec.getSize(heightSpec); Log.i(TAG, "onMeasure called. \nwidthMode " + widthMode + " \nheightMode " + heightSpec + " \nwidthSize " + widthSize + " \nheightSize " + heightSize + " \ngetItemCount() " + getItemCount()); int width = 0; int height = 0; for (int i = 0; i < getItemCount(); i++) { measureScrapChild(recycler, i, View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), mMeasuredDimension); if (getOrientation() == HORIZONTAL) { width = width + mMeasuredDimension[0]; if (i == 0) { height = mMeasuredDimension[1]; } } else { height = height + mMeasuredDimension[1]; if (i == 0) { width = mMeasuredDimension[0]; } } } switch (widthMode) { case View.MeasureSpec.EXACTLY: width = widthSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } switch (heightMode) { case View.MeasureSpec.EXACTLY: height = heightSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } setMeasuredDimension(width, height); } private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) { try { View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException if (view != null) { RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams(); int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, getPaddingLeft() + getPaddingRight(), p.width); int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, getPaddingTop() + getPaddingBottom(), p.height); view.measure(childWidthSpec, childHeightSpec); measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin; measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin; recycler.recycleView(view); } } catch (Exception e) { e.printStackTrace(); } finally { } }}
2.GridLayoutManager和ScrollView进行嵌套
package com.frankzhu.recyclerviewdemo;import android.content.Context;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.View;import android.view.ViewGroup;/** * Author: ZhuWenWu * Version V1.0 * Date: 2015/2/26 14:14. * Description: * Modification History: * Date Author Version Description * ----------------------------------------------------------------------------------- * 2015/2/26 ZhuWenWu 1.0 1.0 * Why & What is modified: */public class FullyGridLayoutManager extends GridLayoutManager { public FullyGridLayoutManager(Context context, int spanCount) { super(context, spanCount); } public FullyGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) { super(context, spanCount, orientation, reverseLayout); } private int[] mMeasuredDimension = new int[2]; @Override public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { final int widthMode = View.MeasureSpec.getMode(widthSpec); final int heightMode = View.MeasureSpec.getMode(heightSpec); final int widthSize = View.MeasureSpec.getSize(widthSpec); final int heightSize = View.MeasureSpec.getSize(heightSpec); int width = 0; int height = 0; int count = getItemCount(); int span = getSpanCount(); for (int i = 0; i < count; i++) { measureScrapChild(recycler, i, View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), mMeasuredDimension); if (getOrientation() == HORIZONTAL) { if (i % span == 0) { width = width + mMeasuredDimension[0]; } if (i == 0) { height = mMeasuredDimension[1]; } } else { if (i % span == 0) { height = height + mMeasuredDimension[1]; } if (i == 0) { width = mMeasuredDimension[0]; } } } switch (widthMode) { case View.MeasureSpec.EXACTLY: width = widthSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } switch (heightMode) { case View.MeasureSpec.EXACTLY: height = heightSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } setMeasuredDimension(width, height); } private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) { if (position < getItemCount()) { try { View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException if (view != null) { RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams(); int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, getPaddingLeft() + getPaddingRight(), p.width); int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, getPaddingTop() + getPaddingBottom(), p.height); view.measure(childWidthSpec, childHeightSpec); measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin; measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin; recycler.recycleView(view); } } catch (Exception e) { e.printStackTrace(); } } }}
3.StaggeredGridLayoutManager和ScrollView进行嵌套
package com.kale.waterfalldemo.extra.RecyclerView;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.StaggeredGridLayoutManager;import android.view.View;import android.view.ViewGroup;/** * @author Jack Tony * @brief 不规则排列(类似于瀑布流)的布局管理器 * @date 2015/4/6 */public class ExStaggeredGridLayoutManager extends StaggeredGridLayoutManager { public ExStaggeredGridLayoutManager(int spanCount, int orientation) { super(spanCount, orientation); } // 尺寸的数组,[0]是宽,[1]是高 private int[] measuredDimension = new int[2]; // 用来比较同行/列那个item罪宽/高 private int[] dimension; @Override public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { // 宽的mode+size final int widthMode = View.MeasureSpec.getMode(widthSpec); final int widthSize = View.MeasureSpec.getSize(widthSpec); // 高的mode + size final int heightMode = View.MeasureSpec.getMode(heightSpec); final int heightSize = View.MeasureSpec.getSize(heightSpec); // 自身宽高的初始值 int width = 0; int height = 0; // item的数目 int count = getItemCount(); // item的列数 int span = getSpanCount(); // 根据行数或列数来创建数组 dimension = new int[span]; for (int i = 0; i < count; i++) { measureScrapChild(recycler, i, View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), measuredDimension); // 如果是竖直的列表,计算item的高,否则计算宽度 //Log.d("LISTENER", "position " + i + " height = " + measuredDimension[1]); if (getOrientation() == VERTICAL) { dimension[findMinIndex(dimension)] += measuredDimension[1]; } else { dimension[findMinIndex(dimension)] += measuredDimension[0]; } } if (getOrientation() == VERTICAL) { height = findMax(dimension); } else { width = findMax(dimension); } switch (widthMode) { // 当控件宽是match_parent时,宽度就是父控件的宽度 case View.MeasureSpec.EXACTLY: width = widthSize; break; case View.MeasureSpec.AT_MOST: break; case View.MeasureSpec.UNSPECIFIED: break; } switch (heightMode) { // 当控件高是match_parent时,高度就是父控件的高度 case View.MeasureSpec.EXACTLY: height = heightSize; break; case View.MeasureSpec.AT_MOST: break; case View.MeasureSpec.UNSPECIFIED: break; } // 设置测量尺寸 setMeasuredDimension(width, height); } private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) { // 挨个遍历所有item if (position < getItemCount()) { try { View view = recycler.getViewForPosition(position);//fix 动态添加时报IndexOutOfBoundsException if (view != null) { RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) view.getLayoutParams(); int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, getPaddingLeft() + getPaddingRight(), lp.width); int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, getPaddingTop() + getPaddingBottom(), lp.height); // 子view进行测量,然后可以通过getMeasuredWidth()获得测量的宽,高类似 view.measure(childWidthSpec, childHeightSpec); // 将item的宽高放入数组中 measuredDimension[0] = view.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; measuredDimension[1] = view.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; recycler.recycleView(view); } } catch (Exception e) { e.printStackTrace(); } } } private int findMax(int[] array) { int max = array[0]; for (int value : array) { if (value > max) { max = value; } } return max; } /** * 得到最数组中最小元素的下标 * * @param array * @return */ private int findMinIndex(int[] array) { int index = 0; int min = array[0]; for (int i = 0; i < array.length; i++) { if (array[i] < min) { min = array[i]; index = i; } } return index; } }
0 0
- ScrolView和RecyclerView嵌套使用的问题
- ScrolView 嵌套ListView 显示不全的问题
- Android 解决ScrolView嵌套GridView冲突问题
- RecyclerView嵌套使用RadioGroup出现的问题
- RecyclerView的嵌套使用
- Scrolview 嵌套ListView 导致ListView条目不能展开的问题及原理详解
- ScrollView和RecyclerView嵌套问题
- ScrollView 和 RecyclerView 嵌套问题
- RecyclerView和ScrollView嵌套使用
- RecyclerView和ScrollView嵌套使用
- RecyclerView和ScrollView嵌套使用
- RecyclerView和ScrollView嵌套使用
- RecyclerView和ScrollView嵌套使用
- 解决ScrollView嵌套RecyclerView 滑动卡顿和嵌套多个RecyclerView 显示不全的问题
- Scrolview嵌套gridView
- 解决ScrollView 和 RecyclerView 嵌套问题
- 21、RecyclerView和ScrollView嵌套使用
- ScrollView嵌套recyclerView出现的滑动问题
- poj 2274 线段树+堆(优先队列)
- Java归并排序
- windows下C语言开发环境搭建
- HDU 1176 免费馅饼(DP)
- 编程的智慧
- ScrolView和RecyclerView嵌套使用的问题
- SQLi Labs Lesson1
- 过滤器应用案例分析
- C++常见知识点总结
- 写一个宏可以将一个数字的奇数位和偶数位交换
- 错误: 找不到或无法加载主类 Main
- 斯坦福机器学习第七周作业中找出最佳C和sigma的代码
- IScroll 实践指南(上)
- PL/SQL Developer(解压版)连接64位的Oracle11g