ListView嵌套GridView使用解析
ListView嵌套GridView使用解析
前言
本文是ListView嵌套GridView的结构。
网上已经解决,不过还是自己做个记录,顺带的了解了解view的测量方案。
问题是嵌套后GridView只能显示一行,这里就涉及到view的高度计算了。
因为GridView是在ListView的条目中,所以他的高度是受到条目高度的控制,item的高度是受到ListView的控制。
解决的方案:
通过改变GridView的高度测量规则来显示完整的GridView。
方案1.
直接改变测量规则,真正的测量工还是交给GridView的默认测量方法。
方案2.
我们手动的去测量每个Item的高度,然后做累加。
上述方案要注意的是,不适合数据量较大的列表,因为上述方案会导致条目无法复用,一次性都加载出来。
看一下GridView的测量源码部分:
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// Sets up mListPaddingsuper.onMeasure(widthMeasureSpec, heightMeasureSpec);
//取出测量规则和期望的宽度和高度int widthMode = MeasureSpec.getMode(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);if (widthMode == MeasureSpec.UNSPECIFIED) {if (mColumnWidth > 0) {widthSize = mColumnWidth + mListPadding.left + mListPadding.right;} else {widthSize = mListPadding.left + mListPadding.right;}widthSize += getVerticalScrollbarWidth();}
//计算出出子view的宽度int childWidth = widthSize - mListPadding.left - mListPadding.right;boolean didNotInitiallyFit = determineColumns(childWidth);
//开始高度计算int childHeight = 0;int childState = 0;
//mAdapter中一共多少个子viewmItemCount = mAdapter == null ? 0 : mAdapter.getCount();final int count = mItemCount;if (count > 0) {final View child = obtainView(0, mIsScrap);AbsListView.LayoutParams p = (AbsListView.LayoutParams) child.getLayoutParams();if (p == null) {p = (AbsListView.LayoutParams) generateDefaultLayoutParams();child.setLayoutParams(p);}p.viewType = mAdapter.getItemViewType(0);p.isEnabled = mAdapter.isEnabled(0);p.forceAdd = true;
//获取子view的测量规则进行测量int childHeightSpec = getChildMeasureSpec(MeasureSpec.makeSafeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),MeasureSpec.UNSPECIFIED), 0, p.height);int childWidthSpec = getChildMeasureSpec(MeasureSpec.makeMeasureSpec(mColumnWidth, MeasureSpec.EXACTLY), 0, p.width);child.measure(childWidthSpec, childHeightSpec);childHeight = child.getMeasuredHeight();childState = combineMeasuredStates(childState, child.getMeasuredState());if (mRecycler.shouldRecycleViewType(p.viewType)) {mRecycler.addScrapView(child, -1);}}
//进行高度的测量if (heightMode == MeasureSpec.UNSPECIFIED) {heightSize = mListPadding.top + mListPadding.bottom + childHeight +getVerticalFadingEdgeLength() * 2;}
//此处是关键,这里是我们使用的最大值模式,就是把所有的view都显示出来。也是我们去干预测量来实现自己想要的显示地方。if (heightMode == MeasureSpec.AT_MOST) {int ourSize = mListPadding.top + mListPadding.bottom;final int numColumns = mNumColumns;for (int i = 0; i < count; i += numColumns) {ourSize += childHeight;if (i + numColumns < count) {ourSize += mVerticalSpacing;}//我们传入的值很大,所以不会走到这里面。if (ourSize >= heightSize) {ourSize = heightSize;break;}}//最后的高度在这里生成。heightSize = ourSize;}if (widthMode == MeasureSpec.AT_MOST && mRequestedNumColumns != AUTO_FIT) {int ourSize = (mRequestedNumColumns*mColumnWidth)+ ((mRequestedNumColumns-1)*mHorizontalSpacing)+ mListPadding.left + mListPadding.right;if (ourSize > widthSize || didNotInitiallyFit) {widthSize |= MEASURED_STATE_TOO_SMALL;}}setMeasuredDimension(widthSize, heightSize);mWidthMeasureSpec = widthMeasureSpec;}
三种测量模式(网上摘取):
1、EXACTLY精确值模式,当我们的控件的layout_width属性和layout_height属性指定为具体数值时,如android:layout_width="100dp",或者为match_parent时系统使用的是EXACTLY模式。2、AT_MOST最大值模式,当控件layout_width属性和layout_height属性为wrap_content时,控件大小随控件子控件或内容变化,此时控件的尺寸只要不超过父控件允许的最大尺寸即可。3、UNSPECIFIED不指定大小测量模式。
下面接着说具体的方法:
以上就是通过改变测量方式来完成全部展示GridView的item的方法。下面给出具体代码。
public class MyGridView extends GridView {public MyGridView(android.content.Context context,android.util.AttributeSet attrs) {super(context, attrs);}/*** 设置不滚动*/@Overridepublic void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //第一个参数传入一个较大的值就可以了int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);super.onMeasure(widthMeasureSpec, expandSpec);}}
结束语
就这么多了��。
ListView嵌套GridView使用解析相关推荐
- android listView嵌套gridview的使用心得
在开发的过程中可能需要用到listview嵌套gridview的场景,但是在Android中, 不能在一个拥有Scrollbar的组件中嵌入另一个拥有Scrollbar的组件,因为这不科学,会混淆滑动 ...
- Flutter中用ListView嵌套GridView报错异常
Flutter中用ListView嵌套GridView报错异常 参考文章: (1)Flutter中用ListView嵌套GridView报错异常 (2)https://www.cnblogs.com/ ...
- 用于解决listview嵌套GridView时显示不全的问题。
package com.yetu.ofmy; import android.view.MotionEvent; import android.widget.ListView; /** * * @Cla ...
- LISTVIEW嵌套GRIDVIEW的一些处理(点击GRIDVIEW的条目,能够显示他在LISTVIEW中的位置)(对这篇文章的优化处理,不每次都new onItemClickListener)...
前几天写了点击GRIDVIEW的条目,能够显示他在LISTVIEW中的位置,当时的处理是在ListView的适配器里的GetView方法里每次都new GridView的onItemClickList ...
- listview嵌套gridview
1.首先要自定义一个继承gridview的类 public class MyGridView extends GridView {public boolean hasScrollBar = true; ...
- android 之 ListView 里面嵌套 GridView 遇到的问题及其解决方法。
我们直接入主题.所有问题例子请参照下图 1,怎样使图片具有点击事件? 答: 解决方法: 在你的BaseAdapter里面不要设置下面这三个东西,然后再设置GridView的onItemClick. g ...
- java 嵌套listview_ListView嵌套GridView使用详解
MainActivity如下: package cn.testlistviewandgridview; import java.util.ArrayList; import java.util.Has ...
- qml lisrview嵌套GridView
研究了2天时间,网上连个例子都没找到.这几天都失眠了!也没有大神指点下...我不想做这个了 list自带title效果,因此.如果想实现带title的网格布局时,只能仿照安卓的思路,listview嵌 ...
- android中ScrollView嵌套ListView或GridView显示位置问题
Android中ScrollView中嵌套ListView或GridView时在开始进入界面时总是显示中间位置,开头的位置显示不出来.这种情况下只需要在ScrollView的父控件中添加以下两行代码即 ...
- 解决Android学习之ScollView嵌套ListView和GridView问题
Android学习之ScollView嵌套ListView和GridView问题,gridview与这种写法一样 import android.content.Context; import andr ...
最新文章
- ECLIPSE 添加插件3种方法
- 前端的各种各样的面试题大全
- 深度洞见|起底元宇宙风潮,如何重塑未来数字营销?
- 电脑故障检测_检测电脑故障的简单方法
- JVM编译时和运行时状态
- 数据结构——线性表的链式表示
- pythonweb服务器部署iis_IIS部署python Web(FLASK试例)
- 低代码平台,JeecgBoot v3.0版本发布—新里程牌开始,迎接VUE3版本到来
- 【SpringCloud从0到6】 第一节:初识微服务微服务的雪崩效应
- dbcp连接池配置详解_重学MySQL:事务与连接池,一文详解带你搞懂
- linux console下的贪吃蛇游戏
- P2P 漏洞曝光,数以百万计的物联网设备被入侵!
- Visual Studio里使用正则表达式进行查找与替换
- u盘数据恢复的原理_电脑磁盘文件数据误删恢复原理、方法总结
- paip.版本控件svn删除文件或目录后的恢复
- 网页中打开msn窗口方法
- OpenPose安装(gtx1650+cuda10.1+cudnn7.6.0+anaconda3)
- SpringBoot + Vue基本知识点荟萃
- 强制使用ie浏览器使用最高版本
- 【paddlepaddle安装报错系列】DLL lond failed:找不到指定模块