android scrollview嵌套listview计算高度的问题
ScrollView中只能放一个控件,一般都放LinearLayout,orientation属性值为vertical。在LinearLayout中放需要呈现的内容。ListView也在其中,ListView的高度设为适应自身内容(wrap_content)。但是为啥在scrollview中嵌套listview会出现只显示第一条listitem的高度呢,原因是:scrollview的ontach方法的滚动事件消费处理,ListView控件的高度设定问题
从谷歌那里找到的ScrollView嵌套ListView只显示一行的解决办法相信很多人都遇到过,然后大部分都是用这位博主的办法解决的吧
刚开始我也是用这个办法解决的,首先感谢这位哥的大私奉献,贴上地址
http://blog.csdn.net/p106786860/article/details/10461015
2、解决的核心代码
- public void setListViewHeightBasedOnChildren(ListView listView) {
- // 获取ListView对应的Adapter
- ListAdapter listAdapter = listView.getAdapter();
- if (listAdapter == null) {
- return;
- }
- int totalHeight = 0;
- for (int i = 0, len = listAdapter.getCount(); i < len; i++) {
- // listAdapter.getCount()返回数据项的数目
- View listItem = listAdapter.getView(i, null, listView);
- // 计算子项View 的宽高
- listItem.measure(0, 0);
- // 统计所有子项的总高度
- totalHeight += listItem.getMeasuredHeight();
- }
- ViewGroup.LayoutParams params = listView.getLayoutParams();
- params.height = totalHeight+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
- // listView.getDividerHeight()获取子项间分隔符占用的高度
- // params.height最后得到整个ListView完整显示需要的高度
- listView.setLayoutParams(params);
- }
这个代码让控件去计算Listview自己的高度然后设置这个Listview的高度
但是这个代码里面有一个问题,就是这个当你的ListView里面有多行的TextView的话,ListView的高度就会计算错误,它只算到了一行TextView的高度,
这个问题在so上的概述为以下:
http://stackoverflow.com/questions/14386584/getmeasuredheight-of-textview-with-wrapped-text
3、终极解决办法
这个问题头疼了一阵后,查找了一下,应该重写一个TextView的onMeasure方法比较好解决
代码有
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- Layout layout = getLayout();
- if (layout != null) {
- int height = (int)FloatMath.ceil(getMaxLineHeight(this.getText().toString()))
- + getCompoundPaddingTop() + getCompoundPaddingBottom();
- int width = getMeasuredWidth();
- setMeasuredDimension(width, height);
- }
- }
- private float getMaxLineHeight(String str) {
- float height = 0.0f;
- float screenW = ((Activity)context).getWindowManager().getDefaultDisplay().getWidth();
- float paddingLeft = ((LinearLayout)this.getParent()).getPaddingLeft();
- float paddingReft = ((LinearLayout)this.getParent()).getPaddingRight();
- //这里具体this.getPaint()要注意使用,要看你的TextView在什么位置,这个是拿TextView父控件的Padding的,为了更准确的算出换行
- int line = (int) Math.ceil( (this.getPaint().measureText(str)/(screenW-paddingLeft-paddingReft))); height = (this.getPaint().getFontMetrics().descent-this.getPaint().getFontMetrics().ascent)*line; return height;}
上面的代码完成更能为,在ListView开始测量时,测量到TextView时,就调用我们的onMeasure方法,我们就可以测量字体的总宽度除与去掉边距的屏幕的大小,就可以算出文字要几行来显示,然后测量字体的高度*行数可以得到字体的总高度,然后在加上上下边距就是TextView真正的高度,然后setMeasuredDimension进去就可以计算出正确的值出来。
完整大代码我贴出来
public class MyListView2 extends LinearLayout {
private BaseAdapter adapter;
private MyOnItemClickListener onItemClickListener;
boolean footerViewAttached = false;
private View footerview;
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.onLayout(changed, l, t, r, b);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
public void notifyChange() {
int count = getChildCount();
if (footerViewAttached) {
count--;
}
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT);
for (int i = count; i < adapter.getCount(); i++) {
final int index = i;
final LinearLayout layout = new LinearLayout(getContext());
layout.setLayoutParams(params);
layout.setOrientation(VERTICAL);
View v = adapter.getView(i, null, null);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (onItemClickListener != null) {
onItemClickListener.onItemClick(MyListView2.this,
layout, index, adapter.getItem(index));
}
}
});
ImageView imageView = new ImageView(getContext());
imageView.setLayoutParams(params);
layout.addView(v);
layout.addView(imageView);
addView(layout, index);
}
}
public MyListView2(Context context) {
super(context);
initAttr(null);
}
public MyListView2(Context context, AttributeSet attrs) {
super(context, attrs);
initAttr(attrs);
}
public void initAttr(AttributeSet attrs) {
setOrientation(VERTICAL);
}
public void initFooterView(final View footerView) {
this.footerview = footerView;
}
public void setFooterViewListener(OnClickListener onClickListener) {
this.footerview.setOnClickListener(onClickListener);
}
public BaseAdapter getAdapter() {
return adapter;
}
public void setAdapter(BaseAdapter adpater) {
this.adapter = adpater;
removeAllViews();
if (footerViewAttached)
addView(footerview);
notifyChange();
}
public void setOnItemClickListener(MyOnItemClickListener onClickListener) {
this.onItemClickListener = onClickListener;
}
public void noMorePages() {
if (footerview != null && footerViewAttached) {
removeView(footerview);
footerViewAttached = false;
}
}
public void mayHaveMorePages() {
if (!footerViewAttached && footerview != null) {
addView(footerview);
footerViewAttached = true;
}
}
public static interface MyOnItemClickListener {
public void onItemClick(ViewGroup parent, View view, int position,
Object o);
}
}
这个adapter就是你获取数据后设置的,也就是上面两点的综合
android scrollview嵌套listview计算高度的问题的更多相关文章
- Android ScrollView 嵌套ListView的替代方案
概要:本例仅提供替代思路. 原需求:实现下图这个布局 要求:头部菜单固定,实现Viewpager.中间的按钮菜单,底部的listview一起能够上下滚动. 做法: 把Viewpager.中间的按钮菜单 ...
- android:ScrollView嵌套ListView的问题
在ScrollView中嵌套使用ListView,看起来ListView只会显示一行多一点,不能滑动.ListView的高度怎么改都有问题,与预期不符合.搜索了一些解决方案,我觉得最好不要用这样的设计 ...
- Android ScrollView 嵌套 ListView、 ListView 嵌套ScrollView Scroll事件冲突解决办法
本人菜鸟一名,最近工作了,开始学习Android. 最近在做项目的时候,UX给了个design,大概就是下拉刷新的ListView中嵌套了ScrollView,而且还要在ScrollView中添加动画 ...
- Android scrollview嵌套listview运行后最先显示出来的位置不在顶部而是中间问题
scrollview里面嵌套了一个listview ,通过设置一个方法设置了listview的高度 现在的情况就是进到这个界面的时候看到的不是最上面 而是中间 ,该问题的解决办法为: mScrollV ...
- android 解决ScrollView嵌套ListView的问题,不能全屏,全屏不能显示下面控件
在开发中遇到ScrollView嵌套ListView的问题,最开始发出不能全屏,效果是这样的: 但我想要的效果是这样的: 下面看一下布局文件: <?xml version="1.0&q ...
- android中ScrollView嵌套ListView或GridView显示位置问题
Android中ScrollView中嵌套ListView或GridView时在开始进入界面时总是显示中间位置,开头的位置显示不出来.这种情况下只需要在ScrollView的父控件中添加以下两行代码即 ...
- 【Android - 问题解决】之ScrollView嵌套ListView时总是自动滑动到ListView顶部的问题
最近做了一个项目,里面有一个ScrollView嵌套ListView的布局. 做出来之后发现,进入这个界面之后,总是自动滑动到ListView的顶部,而ScrollView中位于ListView上面的 ...
- Android——MeasureSpec学习 - 解决ScrollView嵌套ListView和GridView冲突的方法
原文地址:http://blog.csdn.net/yuhailong626/article/details/20639217 在自定义View和ViewGroup的时候,我们经常会遇到int ...
- 关于ScrollView嵌套ListView问题
Android开发之ScrollView中嵌套ListView的解决方案 原文:http://blog.csdn.net/minimicall/article/details/40983331 ...
随机推荐
- Java web 前端面试知识点总结
经过几家大厂面试,目前成功拿到唯品会offer,分享一下我的面试知识点总结: 耦合性:也称块间联系.指软件系统结构中各模块间相互联系紧密程度的一种度量.模块之间联系越紧密,其耦合性就越强,模块的独立性 ...
- poj 2449 Remmarguts' Date 第k短路 (最短路变形)
Remmarguts' Date Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 33606 Accepted: 9116 ...
- 数组中存放对象之java中定义类数组存放类
public class ClassArrayDemo { int age; String name; ClassArrayDemo(int age, String name) { this.age ...
- kindeditor配合requirejs使用时,ready失效
KindEditor官方的文档在使用KindEditor时是这样的: KindEditor.ready(function(K)) { K.create('#editor_id'); } 使用了自己提供 ...
- Spring使用webjar
注意事项 这玩意很简单,但是我们第一次搞就是搞不成功,为什么呢?因为我们都用的是idea或者eclipse编译.webjar只能在maven上才能打包,所以在使用时,记得maven-clean和mav ...
- 未能加载 global.asax的类的解决方案
“/suitecallback”应用程序中的服务器错误. 分析器错误 说明: 在分析向此请求提供服务所需资源时出错.请检查下列特定分析错误详细信息并适当地修改源文件. 分析器错误消息: 未能加载类型“ ...
- CentOS6.8虚拟机安装及ORALCE安装记录
CENTOS6.8安装数据库及设置自启动脚本教程 作者:张欣橙 本文所需要的所有参数均位于文末附录中 一.新建虚拟机 选择下一步 选择下一步 选择稍后安装操作系统 选择LINUX 版本 CentOS ...
- 使用python scipy.optimize linprog和lingo线性规划求解最大值,最小值(运筹学学习笔记)
1.线性规划模型: 2.使用python scipy.optimize linprog求解模型最优解: 在这里我们用到scipy中的linprog进行求解,linprog的用法见https://doc ...
- Docker常见仓库Ubuntu
Ubuntu 基本信息 Ubuntu 是流行的 Linux 发行版,其自带软件版本往往较新一些. 该仓库提供了 Ubuntu从12.04 ~ 14.10 各个版本的镜像. 使用方法 默认会启动一个最小 ...
- Dynamics CRM2013 导入解决方案(快速视图窗体)SystemForm With Id Does Not Exist的解决方法
在CRM2013的环境下导入解决方案报错,具体报错截图如下 根据id去数据库中查找这个id的systemform,确认是存在的,而且通过第二条记录我们也可以看到这个systemform属于哪个实体,我 ...