</pre><pre name="code" class="java">package com.app.util;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ListAdapter;
import android.widget.ListView;
/**
* 解决view高度之类的问题
* @author Wonghoman
*/
public class SetViewUtil {
private final String TAG = "SetViewUtil";
/**
* 动态改变listView的高度
* 计算ExpandableListView的group项的高度的方法(即计算listview合并时的高度的方法)
* 备注:ExpandableListView是listview的子类所以,listview的方法它同样可以使用
*/
public static 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);
listItem.measure(0, 0); // 计算子项View 的宽高
totalHeight += listItem.getMeasuredHeight(); // 统计所有子项的总高度
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
// System.out.println("oldHeight:::"+totalHeight);
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
// System.out.println("newHeight:::"+params.height);
// listView.getDividerHeight()获取子项间分隔符占用的高度
// params.height最后得到整个ListView完整显示需要的高度
listView.setLayoutParams(params);
}
/**
* 可扩展listview展开时调用
* 计算ExpandableListView展开时group下的子view列表的高度的方法
* @param listView
* @param groupPosition
*/
public static void setExpandedListViewHeightBasedOnChildren(
ExpandableListView listView, int groupPosition) {
ExpandableListAdapter listAdapter = listView.getExpandableListAdapter();
if (listAdapter == null) {
return;
}
View listItem = listAdapter.getChildView(groupPosition, 0, true, null,
listView);
listItem.measure(0, 0);
int appendHeight = 0;
for (int i = 0; i < listAdapter.getChildrenCount(groupPosition); i++) {
appendHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
// Log.d(TAG, "Expand params.height" + params.height);
params.height += appendHeight;
listView.setLayoutParams(params);
}
/**
* 可扩展listview收起时调用
* 计算ExpandableListView合并时消除group下的子view列表的高度的方法
* @param listView
* @param groupPosition
*/
public static void setCollapseListViewHeightBasedOnChildren(
ExpandableListView listView, int groupPosition) {
ExpandableListAdapter listAdapter = listView.getExpandableListAdapter();
if (listAdapter == null) {
return;
}
View listItem = listAdapter.getChildView(groupPosition, 0, true, null,
listView);
listItem.measure(0, 0);
int appendHeight = 0;
for (int i = 0; i < listAdapter.getChildrenCount(groupPosition); i++) {
appendHeight += listItem.getMeasuredHeight();
}
/*Log.d(TAG,
"Collapse childCount="
+ listAdapter.getChildrenCount(groupPosition));*/
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height -= appendHeight;
listView.setLayoutParams(params);
}
}
初始化时调用:
SetViewUtil.setListViewHeightBasedOnChildren(expandableListView);
并且监听:
expandableListView.setOnGroupExpandListener(new OnGroupExpandListener() {
@Override
public void onGroupExpand(int groupPosition) {
// TODO Auto-generated method stub
SetViewUtil.setExpandedListViewHeightBasedOnChildren(expandableListView,
groupPosition);
// 更新group每一项的高度
SetViewUtil.setListViewHeightBasedOnChildren(
expandableListView);
}
});
expandableListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {
@Override
public void onGroupCollapse(int groupPosition) {
// TODO Auto-generated method stub
/*
* 计算group下的每一个子项的高度,然后收缩
*/
SetViewUtil.setCollapseListViewHeightBasedOnChildren(expandableListView,
groupPosition);
/*
* 重新评估group的高度
*/
SetViewUtil.setListViewHeightBasedOnChildren(
expandableListView);
}
});
ExpandableListView不能单独设置child之间或group之间的dividerHeight,这点就像listview只有一个dividerHeight(如果希望group之间有dividerHeight而group与child没有dividerHeight是不可能的)
scrollview和listview冲突
现象:设置了listview的高度 ,结果进页面就不是在顶部了
scrollView = ((ScrollView)findViewById(R.id.sv));
scrollView.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
scrollView.scrollTo(0,0);
}
}) ;
也可以试试smoothScrollTo(0,0);
原因:Activity计算窗口的高度是在listview没有填充数据时候就完成了,所以ScrollView嵌套listview需要指定高度,否则就会按照layout中定义的默认高度计算.同样,设置scrollTo的位置也要在listview填充数据完成后调用.
上面无效时, 在代码里去掉listview的焦点 lv.setFocusable(false);
原因:当listview获得focus时移动无效!
ExpandableListView简单应用可以到这里学习:
http://blog.csdn.net/jj120522/article/details/8011586
ExpandableListView有很多项,展开一项则另一个展开的项关闭:
@Override
public void onGroupExpand(int groupPosition) {
// TODO Auto-generated method stub
for (int i = 0; i < mArtistAdapter.getGroupCount(); i++) {
// ensure only one expanded Group exists at every time
if (groupPosition != i && isGroupExpanded(groupPosition)) {
collapseGroup(i);
}
}
}