Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set ListView Height dynamically based on multiline textview inside it

I am using a base adapter to set data in a listview dynamically. I tried to set listview height dynamically. It works perfectly if the textview inside it is single line. However if the textview is multiline, the height is not set properly. The height is set considering single line textview only. How can I set correctly set the height of listview items containing multiline textview. Here's the code:

Fragment code:

ListView mlistNews=(ListView)rootView.findViewById(R.id.news_listView);
mlistNews.setAdapter(new NewsAdapter(getActivity(),params_news));
Utils.setListViewHeightBasedOnItems(mlistNews);

Utility function:

public static boolean setListViewHeightBasedOnItems(ListView listView) {

    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter != null) {

        int numberOfItems = listAdapter.getCount();

        // Get total height of all items.
        int totalItemsHeight = 0;
        for (int itemPos = 0; itemPos < numberOfItems; itemPos++) {
            View item = listAdapter.getView(itemPos, null, listView);
            item.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
            totalItemsHeight += item.getMeasuredHeight();
        }

        // Get total height of all item dividers.
        int totalDividersHeight = listView.getDividerHeight() *
                (numberOfItems - 1);
        // Get padding
        int totalPadding = listView.getPaddingTop() + listView.getPaddingBottom();

        // Set list height.
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalItemsHeight + totalDividersHeight + totalPadding;
        listView.setLayoutParams(params);
        listView.requestLayout();

        return true;

    } else {
        return false;
    }

}

dashboard_list_news.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<TextView
    android:layout_width="0dp"
    android:id="@+id/news_item_text"
    android:layout_weight="1"
    android:layout_height="wrap_content"
    android:layout_gravity="left|center_vertical"
    android:layout_marginLeft="5dp"/>

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/chevron"
    android:layout_gravity="center_vertical|right"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="10dp" />

</LinearLayout>

listView:

<ListView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/rounded_shape_list"
            android:id="@+id/news_listView"
            android:paddingTop="5dp"
            android:paddingBottom="5dp"
            android:divider="#6DCB99"
            android:dividerHeight="1dp" />
like image 387
nlmm01 Avatar asked Mar 24 '15 05:03

nlmm01


1 Answers

As Teemu mentions you need to constrain the width. Sample code below.

float px = 300 * (listView.getResources().getDisplayMetrics().density);
item.measure(View.MeasureSpec.makeMeasureSpec((int)px, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
like image 167
baradas Avatar answered Oct 13 '22 05:10

baradas