代码之家  ›  专栏  ›  技术社区  ›  Cristian

如何配置ListView以自动更改其高度?

  •  4
  • Cristian  · 技术社区  · 14 年前

    我有三个 ListView 同一个窗口中的小部件 LinearLayout . 类似这样的内容(在本例中,我省略了不相关的XML元素):

    <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>
    

    列表视图 高度取其所有列表项之和的确切大小。

    5 回复  |  直到 14 年前
        1
  •  8
  •   durilka    14 年前

    我以这种方式实现了它(代码正在进行中,所以它更像是一个想法源,而不是解决方案):

    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 /滚动视图

    scrollView非常重要,因为您可以很容易地超出屏幕范围。

    由于ListView中的大多数计算方法;Co是包私有的,这对于UI的可公开继承类来说是一个非常奇怪的选择。

        2
  •  3
  •   durilka    13 年前

    这里不是编辑我以前的答案,而是我的实际版本(在案件最终成为问题之后,我不得不修复它)

        @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
  •  3
  •   vuhung3990    9 年前

    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();
    }
    
        4
  •  2
  •   A.G.THAMAYS    8 年前

    列表视图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();
    }
    
        5
  •  1
  •   CommonsWare    14 年前

    您可以尝试在 ListView ViewGroup ),找出他们的高度,求和,然后改变你的想法 列表视图

    话虽如此,我完全认为这会很糟糕:

    • 你需要考虑屏幕的大小,这样你的列表就不会超出屏幕的界限
    • 你需要考虑到方向的变化
    • 等。

    MergeAdapter 我可以在这里帮忙。