Calculate the size of a list view or how to tell it to fully expand

前端 未结 12 873
小蘑菇
小蘑菇 2020-11-29 00:20

I am currently trying to use a ListView inside of a ScrollView. I know from what I\'ve read that this is looked down upon, but I\'m trying to get the ListView to expand com

相关标签:
12条回答
  • 2020-11-29 00:47

    I've been researching on how to do this, and although the question has already been answered, I'd like to provide a solution that I think is better:

    Looking at the ListView's source code you can see the following inside the onMeasure(...) code:

    if (heightMode == MeasureSpec.AT_MOST) {
         // TODO: after first layout we should maybe start at the first visible position, not 0
         heightSize = measureHeightOfChildren(widthMeasureSpec, 0, NO_POSITION, heightSize, -1);
    }
    

    So simply call the listView's measure and pass MeasureSpec.AT_MOST for the height instead of the usual MeasureSpec.UNSPECIFIED.

    I do the following to measure a listview and place it inside a popup-window:

        int widthMeasureSpec = MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels, MeasureSpec.EXACTLY);
        int heightMeasureSpec = MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels, MeasureSpec.AT_MOST);
        mCatalogView.measure(widthMeasureSpec, heightMeasureSpec);
    
        mPopup.setWidth(mCatalogView.getMeasuredWidth());
        mPopup.setHeight(mCatalogView.getMeasuredHeight());
    
    0 讨论(0)
  • 2020-11-29 00:50

    I know it's late and there is already and answer but if you really want to do this there is an easy way:

    Create the list view Item with a defined height

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:orientation="horizontal" >
    
        <ImageView
            android:id="@+id/lvItemSurpriseMeImgRestaurant"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_marginLeft="5dp"
            android:contentDescription="@string/restaurantImageDescriptionColon" />
    </LinearLayout>
    

    Now we know that the Item is 100dp high, and if we know the number of items then it is very simple

    set the ListView height literally to the value of NoOfItems*Height + 10dp extra

    It will never change since all unites are in dp.

    If you have more than 1 item type then calculate it with basic math and set it

            <ListView
                android:id="@+id/menuListView"
                android:layout_width="match_parent"
                android:layout_height="210dp"
                android:layout_weight="1.0"
                tools:ignore="NestedScrolling"
                tools:listitem="@layout/menu_item" >
            </ListView>
    
    0 讨论(0)
  • 2020-11-29 00:51

    Attention! Correct way to calculate height is not

    params.height = getCount() * (old_count > 0 ? getChildAt(0).getHeight() : 0);
    

    We have to add height of each (minus one) divider heights.

    if(oldCount > 0 && getCount() > 0)
        params.height = getCount()
                      * (getChildAt(0).getHeight() + getDividerHeight())
                      - getDividerHeight();
    else
        params.height = 0;
    
    0 讨论(0)
  • 2020-11-29 00:52
    @Override
    public void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
        if (this.isExpanded) {
            final int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec);
            final ViewGroup.LayoutParams params = this.getLayoutParams();
            params.height = this.getMeasuredHeight();
        } else {
           super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
    
    0 讨论(0)
  • 2020-11-29 00:52

    I took the function from djunod's answer (the function in static class)

    calculate listview size

    and change ondraw method as follow. it works after delete operations successfully.

    here is my final class

    class ExpandedListView extends ListView {

    private android.view.ViewGroup.LayoutParams params;
    private int old_count = 0;
    
    public ExpandedListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
    
        if (getCount() != old_count) {
            params = getLayoutParams();
            old_count = getCount();
            int totalHeight = 0;
            for (int i = 0; i < getCount(); i++) {
                this.measure(0, 0);
                totalHeight += getMeasuredHeight();
            }
    
            params = getLayoutParams();
            params.height = totalHeight + (getDividerHeight() * (getCount() - 1));
            setLayoutParams(params);
        }
    
        super.onDraw(canvas);
    }
    

    }

    now my listview expands after row insert without scrolling. and after row delete this code calculates the correct size for listview. i don't know how it is working. but it is working. BR

    0 讨论(0)
  • 2020-11-29 00:59

    use this will be worked:

    public class ListViewEx extends ListView {
    
    public ListViewEx(Context context) {
        super(context);
    }
    
    /**
     * @param context
     * @param attrs
     */
    public ListViewEx(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    /**
     * 设置不滚动
     */
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);
    }
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        return ev.getAction()==MotionEvent.ACTION_MOVE||super.dispatchTouchEvent(ev);
    }
    

    }

    0 讨论(0)
提交回复
热议问题