2010-07-28 34 views
4

我有三个ListView部件在相同的LinearLayout。像这样的东西(我省略不在此例相关的XML元素):如何配置ListView自动更改其高度?

<LinearLayout> 
    <ListView 
     android:layout_width="fill_parent" 
     android:layout_height="360dp"/> 
    <ListView 
     android:layout_width="fill_parent" 
     android:layout_height="360dp"/> 
    <ListView 
     android:layout_width="fill_parent" 
     android:layout_height="360dp"/> 
</LinearLayout> 

这迫使名单有360倾角的高度。当然,即使列表项目很少,这也是它的高度。所以,我的问题是如何使列表具有自动高度?我想要的是,ListView高度取所有列表项的总和的确切大小。

+0

你能告诉我们你为什么要打3名列表视图在这样的LinearLayout内?也许有更好的方法来解决你的问题。正如你可能已经从答案中拿出的那样,你将不得不编写一些烦人的详细代码来使它在所有情况下都能正常工作。你确定你不只是想要一个LinearLayout的项目直接在它里面吗?如果ListViews只是这样,你可以使用一些适配器,你可能会合并所有的适配器结果到一个? – Hamy 2010-07-29 06:12:52

+0

是的,那里肯定有一个UI设计问题。虽然,这是一个源代码,有人留在我最近参加的一个项目中,截止日期是今天。所以,老板告诉我要做的只是让它看起来更好,而不是重构整个应用程序。当然,我会在未来尝试解决这个问题。 – Cristian 2010-07-29 12:24:15

回答

8

我实现这种方式(代码正在进行工作,所以它比解决方案的想法源):

package com.customcontrols; 
public class NoScrollListView extends ListView 
{ 
    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
    { 
     super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0)); 

     // here I assume that height's being calculated for one-child only, seen it in ListView's source which is actually a bad idea 
     int childHeight = getMeasuredHeight() - (getListPaddingTop() + getListPaddingBottom() + getVerticalFadingEdgeLength() * 2); 

     int fullHeight = getListPaddingTop() + getListPaddingBottom() + childHeight*(getCount()); 

     setMeasuredDimension(getMeasuredWidth(), fullHeight); 
    } 
} 

计算并不完美,但它很接近,到目前为止的作品。 后,你只需创建这样一个布局:

滚动型 com.customcontrol.NoScrollListView com.customcontrol.NoScrollListView com.customcontrol.NoScrollListView /滚动型

了滚动的至关重要的,因为你可以很容易用完屏幕边界。

PS。由于ListView & Co中的大多数计算方法都是封装私有,这对于公共可继承的UI类非常奇怪,因此计算的直肠驱动。

+0

查看下面我支持不同高度项目的演变版本 – durilka 2011-01-19 11:32:37

+0

#1 - 不要将其他答案称为“上方”或“下方”。 StackOverflow上的答案通常按分数排序,这可以改变超时而不是时间,这是不可改变的。 #2 - 为什么不编辑您现有的答案以包含部分实施和完全实施的代码?无论哪种方式,感谢您的帮助:) – ArtOfWarfare 2012-10-15 13:50:26

+0

在我的评论从2010年7月28日,请阅读“以后”而不是“下面”。 – durilka 2012-10-18 20:00:48

1

您可以尝试迭代ListView的行(请参阅ViewGroup上的方法),查找它们的高度,将它们相加,然后更改高度。

话虽这么说,我完全相信这是可怕的:

  • 你需要考虑到屏幕大小,让您的列表不走过去的屏幕范围
  • 您需要考虑到定向改变
  • 你需要考虑任何修改您的数据(例如,删除行可能需要您的列表萎缩)
  • 等等

如果您的目标确实是要有一个列表,但您有三个数据源,请合并数据并将其放入一个列表中。我的MergeAdapter可以在这里帮助。

3

相反编辑我以前的答案的,这里是我的实际版本(后终于情况成了问题,我不得不解决它)

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
{ 
    super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0)); 

    int childHeight = getMeasuredHeight() - (getListPaddingTop() + getListPaddingBottom() + getVerticalFadingEdgeLength() * 2); 

    // on a first run let's have a space for at least one child so it'll trigger remeasurement 
    int fullHeight = getListPaddingTop() + getListPaddingBottom() + childHeight*(getCount()); 

    int newChildHeight = 0; 
    for (int x = 0; x<getChildCount(); x++){ 
     View childAt = getChildAt(x); 

     if (childAt != null) { 
      int height = childAt.getHeight(); 
      newChildHeight += height; 
     } 
    } 

    //on a second run with actual items - use proper size 
    if (newChildHeight != 0) 
     fullHeight = getListPaddingTop() + getListPaddingBottom() + newChildHeight; 

    setMeasuredDimension(getMeasuredWidth(), fullHeight); 
} 

最棘手的部分是,onMeasure被调用两次,第一次为大约布局,然后后添加一个精确的项目,都必须返回理智的结果。

3

我发现set ListView Height Based On Children的解决方案,这项工作

public static void setListViewHeightBasedOnChildren(ListView listView) { 
    ListAdapter listAdapter = listView.getAdapter(); 
    if (listAdapter == null) { 
     // pre-condition 
     return; 
    } 

    int totalHeight = 0; 
    for (int i = 0; i < listAdapter.getCount(); i++) { 
     View listItem = listAdapter.getView(i, null, listView); 
     listItem.measure(0, 0); 
     totalHeight += listItem.getMeasuredHeight(); 
    } 

    ViewGroup.LayoutParams params = listView.getLayoutParams(); 
    params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); 
    listView.setLayoutParams(params); 
    listView.requestLayout(); 
} 
1

试试这个...列表视图实际高度

列表视图XML编码

<ListView 
android:id="@+id/my_listview" 
android:layout_width="match_parent" 
android:layout_height="match_parent" /> 

列表视图Java编码

ListView lView = (ListView)findViewById(R.id.my_listview); 
    lView.setAdapter(adapter); 
    setListViewHeightBasedOnChildren(lView); 

setListViewHeightBasedOnChildren方法

public static void setListViewHeightBasedOnChildren(ListView listView) { 
    ListAdapter listAdapter = listView.getAdapter(); 
    if (listAdapter == null) { 
     return; 
    } 

    int totalHeight = 0; 
    for (int i = 0; i < listAdapter.getCount(); i++) { 
     View listItem = listAdapter.getView(i, null, listView); 
     listItem.measure(0, 0); 
     totalHeight += listItem.getMeasuredHeight(); 
    } 

    ViewGroup.LayoutParams params = listView.getLayoutParams(); 
    params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); 
    listView.setLayoutParams(params); 
    listView.requestLayout(); 
}