我们的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];@Overridepublic 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 动态添加时报IndexOutOfBoundsExceptionif (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];@Overridepublic 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 动态添加时报IndexOutOfBoundsExceptionif (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;@Overridepublic void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {// 宽的mode+sizefinal int widthMode = View.MeasureSpec.getMode(widthSpec);final int widthSize = View.MeasureSpec.getSize(widthSpec);// 高的mode + sizefinal 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) {// 挨个遍历所有itemif (position < getItemCount()) {try {View view = recycler.getViewForPosition(position);//fix 动态添加时报IndexOutOfBoundsExceptionif (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;}}

Android RecyclerView和ScrollView嵌套使用相关推荐

  1. Android之解决ScrollView嵌套RecycleView导致滑动冲突或者显示不全的问题

    1 问题 ScrollView嵌套RecycleView导致滑动冲突或者显示不全的问题 2 解决办法 1).ScrollView替换成普通布局,然后RecycleView用的BaseMultiItem ...

  2. [转]Android笔记:ScrollView嵌套ViewPager的滚动冲突解决方法

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 /**  * ...

  3. android list嵌套list,Android开发日常-listVIiew嵌套webView回显阅读位置

    详情页布局结构 需求是回显webview展示网页的阅读位置 方案1: 使用webview.getScrollY()获取滑动到的位置,用setScrollY()回显设置, 但是两个方法都出现了问题,ge ...

  4. 【Android】ListView、RecyclerView、ScrollView里嵌套ListView 相对优雅的解决方案:NestFullListView

    一 背景概述: ScrollView里嵌套ListView,一直是Android开发者(反正至少是我们组)最讨厌的设计之一,完美打破ListView(RecyclerView)的复用机制,成功的将Na ...

  5. Android Scrollview嵌套RecyclerView导致滑动卡顿问题解决(屡试不爽)

    今天开发的一个项目首页,布局还是比较复杂的,各种滑动冲突,(Banner+横向RecyclerView+纵向RecyclerView(item又是横向的RecyclerView)),  最外面的框架用 ...

  6. NestedScrollView/ScrollView嵌套Recyclerview,导致Recyclerview抢占焦点,置顶了, 修改好后,引起Edittext又不能点击问题处理

    NestedScrollView/ScrollView嵌套Recyclerview,导致Recyclerview抢占焦点,置顶了, 修改好后,引起Edittext又不能点击问题处理 NestedScr ...

  7. 【Android 手势冲突】Colin带你彻底解决RecyclerView与ScrollView滑动冲突问题,并实现RecyclerView悬停导航栏(附demo哦)

    在新一期的需求中,产品要求我们做出和美团某个页面类似的功能,即一个页面包含在scrollView中,上面一个部分放置一些常用的广告banner.宫格tab等,下面放置一个RecyclerView用于展 ...

  8. android中ScrollView嵌套ListView或GridView显示位置问题

    Android中ScrollView中嵌套ListView或GridView时在开始进入界面时总是显示中间位置,开头的位置显示不出来.这种情况下只需要在ScrollView的父控件中添加以下两行代码即 ...

  9. 在android中ScrollView嵌套ScrollView解决方案

    文章转载自:http://www.jb51.net/article/33054.htm 大家好,众所周知,android里两个相同方向的ScrollView是不能嵌套的,那要是有这样的需求怎么办,接下 ...

最新文章

  1. 查看磁盘空间,清理缓存
  2. c#后台修改前台DOM的css属性
  3. struts2 action重定向
  4. 《大话操作系统——做坚实的project实践派》(6)
  5. 2019最新 Java商城秒杀系统的设计与实战视频教程(SpringBoot版)
  6. 微信开发实现一键拨号出现屏蔽问题的解决方案
  7. 恒大汽车向技术人员等授出3.24亿股购股权:占公司股本的3.31%
  8. Err:error occurred at recursive SQL level 1
  9. JavaEye被CSDN收购
  10. c语言编程技术列表,C语言系统编程技术点
  11. 删除讨厌的4199流氓软件
  12. 1 0.99999的悖论_天文学科普:带你了解反物质、费米悖论和黑洞
  13. 怎么恢复360删除的文件?360文件恢复,快速完成
  14. System.DllNotFoundException: Unable to load DLL 'XX.dll': 找不到指定的模块。 (Exception from HRESULT:
  15. IPv6的TSO/GRO/GSO及其Linux实现的不妥
  16. Endnote下载的pdf文件合并到同一个文件夹
  17. 助力中国“智”造,携客云SRM“好产品”是如何炼成的?
  18. 计算机类专业中对数学物理要求低的,哪些专业对数学和物理要求比较高
  19. 谈一谈网络编程学习经验(陈硕)
  20. win10 smb共享硬盘

热门文章

  1. echarts中x轴文字过长换行处理和倾斜处理。
  2. Vue采用input实现文件上传与删除
  3. 终端报错xcrun: error: unable to find utility “xcodebuild”, not a developer tool or
  4. React+Redux仿Web追书神器
  5. commons-csv 使用记叙
  6. MySql字符串函数使用技巧
  7. asp.net(c#)将彩色图片变灰阶图片
  8. 搭建discuz论坛
  9. 推荐一款生成SQL插入语句的软件
  10. catboost进行分类并开启GPU模式