Is it possible to set listView maxHeight in xml?
Asked Answered
S

1

5

Having a listView, if it has less content its height should go with "wrap_content". If it has more rows the max height should be limit to some height.

It is allowed to set android:maxHeight in ListView:

<ListView>
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:maxHeight="120dp"
</ListView>

but it does not work and always "wrap_content". There only way to make it work is in code use

int cHeight = parentContainer.getHeight();
ViewGroup.LayoutParams lp = mListView.getLayoutParams();

if (messageListRow > n) 
{
    lp.height = (int)(cHeight * 0.333);
} 
else 
{
    lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
}

mListView.setLayoutParams(lp);

Is there a way to do it in xml?

Stereotropism answered 4/5, 2015 at 17:43 Comment(2)
Don't use "wrap_content" for the height of a listview, as it will cause your adapter to be called multiple times. Why don't you put your listview in a LinearLayout container, and control the height based on your needs instead.Newhall
Good point, thanks Pztar. But even put in a LinearLayout container it is still problem to define the container's height. Maybe to dynamically set in code is the only way.Stereotropism
J
10

Yes, you can have your custom ListView with a maxHeight property.

Step 1. Create attrs.xml file inside the values folder and put the following code:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="ListViewMaxHeight">
        <attr name="maxHeight" format="dimension" />
    </declare-styleable>

</resources>

Step 2. Create a new class (ListViewMaxHeight.java) and extend the ListView class:

package com.example.myapp;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.widget.ListView;

public class ListViewMaxHeight extends ListView {

    private final int maxHeight;

    public ListViewMaxHeight(Context context) {
        this(context, null);
    }

    public ListViewMaxHeight(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ListViewMaxHeight(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        if (attrs != null) {
            TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ListViewMaxHeight);
            maxHeight = a.getDimensionPixelSize(R.styleable.ListViewMaxHeight_maxHeight, Integer.MAX_VALUE);
            a.recycle();
        } else {
            maxHeight = 0;
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
        if (maxHeight > 0 && maxHeight < measuredHeight) {
            int measureMode = MeasureSpec.getMode(heightMeasureSpec);
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, measureMode);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

}

Step 3. In the xml file of your layout:

<com.example.myapp.ListViewMaxHeight
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:maxHeight="120dp" />
Joust answered 4/5, 2015 at 18:54 Comment(2)
This is not a good solution. I used it and in my adapter, and i saw that items position didn't have true value.Corpulence
Works perfectly. Thank youPhotophore

© 2022 - 2024 — McMap. All rights reserved.