代码之家  ›  专栏  ›  技术社区  ›  Maksym Gontar

Android-获取ListView项目高度?

  •  18
  • Maksym Gontar  · 技术社区  · 15 年前

    当列表中没有实际的项目时,是否有方法在代码中获取ListViewItem高度?

    我的ListViewItem布局:

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="?android:attr/listPreferredItemHeight">
    ...
    </LinearLayout>  
    

    我试过用充气器来充气:

    View convertView = LayoutInflater.from( this )
        .inflate( R.layout.mail_list_row, null );
    int itemHeight = convertView.getHeight();
    

    但返回0;

    谢谢!

    4 回复  |  直到 10 年前
        1
  •  4
  •   Amit Chintawar    15 年前

    在Android中,只有在渲染完成后,视图才被分配宽度和高度。因此,除非列表至少呈现一次,否则无法获得listemheight。解决问题的方法可能是设置列表项的最小高度,这样至少可以使用某些内容,而不是硬编码高度和宽度。

        2
  •  42
  •   TWiStErRob    10 年前

    试试这个,它会对你有用的。

    private static final int UNBOUNDED = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
    
    // To calculate the total height of all items in ListView call with items = adapter.getCount()
    public static int getItemHeightofListView(ListView listView, int items) {
        ListAdapter adapter = listView.getAdapter();
    
        int grossElementHeight = 0;
        for (int i = 0; i < items; i++) {
            View childView = adapter.getView(i, null, listView);
            childView.measure(UNBOUNDED, UNBOUNDED);
            grossElementHeight += childView.getMeasuredHeight();
        }
        return grossElementHeight;
    }
    
        3
  •  11
  •   ashakirov    10 年前

    的优化版本 Dwivedi Ji 带分隔符高度和不带不必要参数的代码:

    private int calculateHeight(ListView list) {
    
        int height = 0;
    
        for (int i = 0; i < list.getCount(); i++) {
            View childView = list.getAdapter().getView(i, null, list);
            childView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            height+= childView.getMeasuredHeight();
        }
    
        //dividers height
        height += list.getDividerHeight() * list.getCount();
    
        return height;
    }
    
        4
  •  2
  •   Mike Kogan    11 年前

    正如Hariseldon78所指出的,这些解决方案都不能解决实际问题,即在呈现列表项行之前确定列表项行的高度。我有同样的问题,因为我想将一些图像缩放到ListView项目行的高度,而不想将它们缩放到固定值。如果主题导致行布局其他部分中的文本高度不同,那么我需要高度,以便在适配器的getview例程中可以相应地调整bmap的大小。我一直在努力解决GetHeight和所有测量高度报告为零的问题,直到行被呈现出来。对我来说,后来看到正确的高度太晚了。

    我的解决方案是第一次通过getView创建OnlyoutChangedListener(),只为第0行创建。一旦第一个位置(0)的getview完成执行,监听器将立即触发,此时“bottom”参数将告诉您行的高度。我将它记录在一个自定义适配器类变量中,这样它就可以作为高度参数使用,而不必再次获取高度。

    侦听器在执行过程中注销自身。这为第1-n行提供了适当的高度,但不为第0行提供。对于第零排,我做了一些非常糟糕的事情。在设置了另一个自定义适配器类变量来控制递归之后,我的侦听器再次调用了第0行的getview。第二次运行getview(0)时,它将不会设置侦听器,并且会找到一个有效的高度参数来操作,所有参数都是好的。

    下面是代码-不需要告诉我这有多糟糕-如果Android不必让它如此难以判断我创建的视图有多大,当我完成填充视图的时候,基于表面的渲染参数,我不必做这种丑陋,但它工作。抱歉,如果代码格式太差…

    int mHeight = 0;
    
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
    ... usual boiler plate stuff
        // JUST THE FIRST TIME
        if (position == 0 && mHeight == 0) {
            final View ref = convertView;
            convertView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                public void onLayoutChange(View v, int left, int top, int right,
                       int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                        ref.removeOnLayoutChangeListener(this);
                        mHeight = bottom;
                        firstTime = false;
    
                        //  NOW LETS REGET THE FIRST VIEW WITH THE HEIGHT CORRECT
                        int visiblePosition = getListView().getFirstVisiblePosition();
                        View view = getListView().getChildAt(0 - visiblePosition);
                        getListAdapter().getView(0, view, getListView());
                        // RECURSION LOL
                }
            });
        }
    
        // Configure the view for this row
        ....
    
        // HOW BIG IS THE VIEW?
        // NOW IF NOT FIRSTTIME (MHEIGHT != 0)
        if (mHeight != 0) {
            // DO OUR IMAGE SETUP HERE CAUSE mHeight is RIGHT!
            Log.d(TAG, "mHeight=" + mHeight);
        }
    
            return convertView;
    }