Android RecyclerView和ScrollView嵌套使用
生活随笔
收集整理的這篇文章主要介紹了
Android RecyclerView和ScrollView嵌套使用
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
我們的recyclerView有多個(gè)layoutmanager,通過(guò)重寫layoutmanager的方法就可以讓recyclerView和ScrollView嵌套了。但是請(qǐng)注意,如果recyclerView很長(zhǎng)那么強(qiáng)烈不建議去做嵌套,因?yàn)檫@樣recyclerView會(huì)在展示的時(shí)候立刻展示所有內(nèi)容,效率極低。
本文的兩部分代碼來(lái)自一個(gè)博主的博客,另一個(gè)是我自己寫的,正好可以完全適用于現(xiàn)有的layoutmanager。大家需要的話可以試試,應(yīng)該問(wèn)題不大。
原博主的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 動(dòng)態(tài)添加時(shí)報(bào)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進(jìn)行嵌套
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 動(dòng)態(tài)添加時(shí)報(bào)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進(jìn)行嵌套
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 不規(guī)則排列(類似于瀑布流)的布局管理器* @date 2015/4/6*/ public class ExStaggeredGridLayoutManager extends StaggeredGridLayoutManager {public ExStaggeredGridLayoutManager(int spanCount, int orientation) {super(spanCount, orientation);}// 尺寸的數(shù)組,[0]是寬,[1]是高private int[] measuredDimension = new int[2];// 用來(lái)比較同行/列那個(gè)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的數(shù)目int count = getItemCount();// item的列數(shù)int span = getSpanCount();// 根據(jù)行數(shù)或列數(shù)來(lái)創(chuàng)建數(shù)組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);// 如果是豎直的列表,計(jì)算item的高,否則計(jì)算寬度//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) {// 當(dāng)控件寬是match_parent時(shí),寬度就是父控件的寬度case View.MeasureSpec.EXACTLY:width = widthSize;break;case View.MeasureSpec.AT_MOST:break;case View.MeasureSpec.UNSPECIFIED:break;}switch (heightMode) {// 當(dāng)控件高是match_parent時(shí),高度就是父控件的高度case View.MeasureSpec.EXACTLY:height = heightSize;break;case View.MeasureSpec.AT_MOST:break;case View.MeasureSpec.UNSPECIFIED:break;}// 設(shè)置測(cè)量尺寸 setMeasuredDimension(width, height);}private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,int heightSpec, int[] measuredDimension) {// 挨個(gè)遍歷所有itemif (position < getItemCount()) {try {View view = recycler.getViewForPosition(position);//fix 動(dòng)態(tài)添加時(shí)報(bào)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進(jìn)行測(cè)量,然后可以通過(guò)getMeasuredWidth()獲得測(cè)量的寬,高類似 view.measure(childWidthSpec, childHeightSpec);// 將item的寬高放入數(shù)組中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;}/*** 得到最數(shù)組中最小元素的下標(biāo)** @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;}}?
總結(jié)
以上是生活随笔為你收集整理的Android RecyclerView和ScrollView嵌套使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 防止按钮重复点击 模型转字典 接口传参不
- 下一篇: 为什么 PHP 中 this 和 sel