Android中ListView嵌套GridView的简单消息流UI(解决宽高问题)
最近搞一个项目,需要用到类似于新浪微博的消息流,即每一项有文字、有九宫格图片,因此这就涉及到ListView或者ScrollView嵌套GridView的问题。其中GridView的高度问题在网上都很容易找到答案,即覆写onMeasure方法,然后设置高度的MeasureSpec。但是宽度问题确实没有什么资料,这里所说的宽度问题是比如GridView的列数为3,那么即使只有一张图片,gridview的宽度也是match_parent的,导致用户点击在图片范围外但是在gridview范围内时ListView的点击事件不能捕获。
如图 :
出现的问题截图如上,当只有一个图标时GridView的宽度(灰色区域)也是match_parent的,这个时候点击gridview区域是ListView是不能响应的,但是如果GridView的背景色与ListView的背景一致,用户是看不到GridView的宽度,当用户点击图片以外的区域,可能的操作就是进入到该条消息的详情页,但是由于此时GridView是match_parent的,所以ListView根本不会获取到点击事件,这样的体验很不好。我们需要的效果是这样的 :
即GridView的大小刚好能够包含图片的大小,这样当GridView的背景色为默认时,用户点击图片以外的区域就是点击了ListView的Item。
我们看看如何解决这个问题吧,首先布局方面就不讲了,主要还是讲讲GridView的宽高问题吧。解决GridView的高度问题,需要覆写GridView的onMeasure方法,代码如下 :
public class MGridView extends GridView { public boolean hasScrollBar = true; /**
* @param context
*/
public MGridView(Context context) {
this(context, null);
} public MGridView(Context context, AttributeSet attrs) {
super(context, attrs, );
} public MGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = heightMeasureSpec;
if (hasScrollBar) {
expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> ,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);// 注意这里,这里的意思是直接测量出GridView的高度
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
} }
在onMeasure方法中,因为hasScrollBase为true, 我们会注意到代码中有注释的分支。这里实际上就是在onMeasure的时候计算出GridView的高度,而不是只计算其中几个View的高度。如果没有这一步,那么GridView的高度将显示不全。将GridView的高度计算出来,这样就不需要上下滑动来显示其它的item了,因为问题所在就是GridView嵌套在了ScrollView或者包含ScrollView的组件中,从而引发的冲突。
下面解决宽度的问题,思路就是在ListView的getView方法中手动计算每个GridView的图片个数,如果图片个数小于GridView每行的列数,则手动计算每个child view所需的宽度,然后GridView的宽度 = child个数 * 每个child view的宽度。为了避免重复计算,我们会缓存计算结果。计算代码如下 :
/**
* @author mrsimple
*/
public final class GridViewUtils {
/**
* 存储宽度
*/
static SparseIntArray mGvWidth = new SparseIntArray(); /**
* 计算GridView的高度
*
* @param gridView 要计算的GridView
*/
public static void updateGridViewLayoutParams(MGridView gridView, int maxColumn) {
int childs = gridView.getAdapter().getCount(); if (childs > ) {
int columns = childs < maxColumn ? childs % maxColumn : maxColumn;
gridView.setNumColumns(columns);
int width = ;
int cacheWidth = mGvWidth.get(columns);
if (cacheWidth != ) {
width = cacheWidth;
} else { // 计算gridview每行的宽度, 如果item小于3则计算所有item的宽度;
// 否则只计算3个child宽度,因此一行最多3个child。 (这里我们以3为例)
int rowCounts = childs < maxColumn ? childs : maxColumn;
for (int i = ; i < rowCounts; i++) {
View childView = gridView.getAdapter().getView(i, null, gridView);
childView.measure(, );
width += childView.getMeasuredWidth();
}
} ViewGroup.LayoutParams params = gridView.getLayoutParams();
params.width = width;
gridView.setLayoutParams(params);
if (mGvWidth.get(columns) == ) {
mGvWidth.append(columns, width);
}
}
}
ListView的getView方法如下 :
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null; if (convertView == null) {
convertView = mInflater.inflate(R.layout.listview_item, parent, false);
viewHolder = new ViewHolder();
viewHolder.mGridView = (MGridView) convertView.findViewById(R.id.my_gridview);
viewHolder.mTextView = (TextView) convertView.findViewById(R.id.my_tv);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
} final ListViewItem item = getItem(position);
// 设置GridView的Adapter
viewHolder.mGridView.setAdapter(new GridViewAdapter(mContext, item.mImages));
// 计算GridView宽度, 设置默认为numColumns为3.
GridViewUtils.updateGridViewLayoutParams(viewHolder.mGridView, );
viewHolder.mTextView.setText(item.mText);
return convertView;
}
这样,我们就解决了消息流的宽高问题。
Android中ListView嵌套GridView的简单消息流UI(解决宽高问题)的更多相关文章
- 【Android】listview 嵌套gridview报错,代码:”during second layout pass: posting in next frame
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985, QQ986945193 公众号:程序员小冰 说明:本人曾经在listview嵌套gridview出现 ...
- Android中ScrollView嵌套GridView,解决GridView显示不全的问题
/** * 自定义gridview,解决ScrollView中嵌套gridview显示不正常的问题(1行半) * */ public class MyGridView extends GridView ...
- Android中ListView嵌套进ScrollView时高度很小的解决方案
package com.example.test.util; import android.view.View; import android.view.ViewGroup; import andro ...
- android中listview的item滑动删除效果(已解决listview点击问题)
领导看到iphone上tableview有个滑动删除的效果,要求在android上也实现,搜了下资料,实现起来比较简单,可弄到后面,居然不能点击了,把一篇文章中的代码修改了一下,捣鼓了一番,搞定,下面 ...
- android中ListView控件最简单的用法
创建一个活动,在xml文件中添加一个ListView控件,id定义为list1,并且设置为满屏显示,代码如下: <ListView android:id="@+id/list1&quo ...
- Android 中 ListView Adapter getView 被多次调用问题 解决方法
执行多次原因是因为每显示一个VIew,它都去测量view的高度,执行measure方法,导致getView执行多次. 解决方法是将 ListView 的 layout_width 设置为 fill_p ...
- android listView嵌套gridview的使用心得
在开发的过程中可能需要用到listview嵌套gridview的场景,但是在Android中, 不能在一个拥有Scrollbar的组件中嵌入另一个拥有Scrollbar的组件,因为这不科学,会混淆滑动 ...
- ScrollView嵌套ListView嵌套GridView的上下拉以及加载更多
ScrollView 效果 ScrollView 说明 一个ScrollView 嵌套ListView 嵌套GridView的上拉加载更多,下拉刷新的demo. 主要是重写了GridView和Lsit ...
- ListView嵌套GridView
首先,我们通过两个实例来了解下本篇文章所讲的重点,看下图: 微博: 陌陌: 大家应该对这两款软件并不陌生,接下来,我将列举下本文将要实现的几个点: 1.ListView嵌套GridView,互不冲突, ...
随机推荐
- BrainFuck语言生成器
还要求生成的代码比较快和短. 当然stackexchange上面给出了实现,java的 http://codegolf.stackexchange.com/questions/5418/brainfu ...
- authbind start tomcat services as user with less that 1024 ports. linux常规用户使用tomcat的80端口
Start tomcat services using authbind this will allow user to start ports less than 1024 we do not ne ...
- IDF实验室解题学习笔记1
1.图片里的英文 图片可以有很多种打开方式,破解该题,需将图片下载下来. 对于图片,我们可以使用图片编辑软件,进行各种调明暗,变色调等操作. 我们还可以使用2进制或者16进制的文件打开方式打开.该图使 ...
- Vericant维立克 | 氪加
Vericant维立克 | 氪加 Vericant维立克
- 关于bootstrap--表格(tr的各种样式)
只需要<tr class="active">就可以用active样式. 特别提示:除了”.active”之外,其他四个类名和”.table-hover”配合使用时,Bo ...
- Thinkphp显示系统常量信息的方法(php的用法)
输入 :public function Main() { dump(get_defined_constants(true)); }显示系统信息, 其中: 'APP_PATH' ...
- eclipse指定启动时的jdk(xjl456852原创)
在eclipse安装目录中找到eclipse.ini 在第一行配置(即可启动按指定版本的jdk启动eclipse): -vm D:\soft\Java\jre8\bin\server\jvm.dll ...
- jQuery鼠标悬停图片放大显示
jQuery鼠标悬浮放于图片上之后图片放大显示的效果,即鼠标移到图片上图片突出显示,鼠标移开后恢复原来的模样,你可以在图片滚动效果中加上本特效,相信会更炫一些. <!DOCTYPE html P ...
- C# 合成图片
教师节快到了,给那些年的老师拼个图 前端有脸.眉.眼.特征.气泡等多元素图片 后端将最后选中元素的ID,合成“脸谱” /// <summary> /// 合并图片 /// </sum ...
- debian 源
把下面的源覆盖在/etc/apt/sources.list deb http://http.debian.net/debian wheezy main deb-src http://http.debi ...