【问题标题】:Getting total height of items in ListView not working with dynamic lines in TextView获取 ListView 中项目的总高度不适用于 TextView 中的动态行
【发布时间】:2017-10-16 03:26:03
【问题描述】:

我有一个 Listview,我需要在其中获取所有项目的总高度和,以便 ListView 高度等于所有项目的高度。我尝试实现以下类来实现这一点。

public class UIUtils {

    /**
     * Sets ListView height dynamically based on the height of the items.
     *
     * @param listView to be resized
     * @return true if the listView is successfully resized, false otherwise
     */
    public static boolean setListViewHeightBasedOnItems(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if(listAdapter != null)
        {
            int numberOfItems = listAdapter.getCount();
            WindowManager wm = (WindowManager) listView.getContext().getSystemService(Context.WINDOW_SERVICE);
            Display display = wm.getDefaultDisplay();
            int deviceWidth;

            if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
                Point size = new Point();
                display.getSize(size);
                deviceWidth = size.x;
            } else {
                deviceWidth = display.getWidth();
            }

            int desiredWidth = View.MeasureSpec.makeMeasureSpec(deviceWidth, View.MeasureSpec.AT_MOST);
            int desiredHeight = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);

            // 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(desiredWidth, desiredHeight);
                totalItemsHeight += item.getMeasuredHeight();
            }

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

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

            return true;
        }
        else
        {
            return false;
        }
    }
}

这是我最终如何使用前面描述的类:

ListView list = (ListView) findViewById(R.id.bills);
BillsListViewAdapter listViewAdapter = new BillsListViewAdapter(context, R.layout.item_bill, bills);
list.setAdapter(listViewAdapter);
UIUtils.setListViewHeightBasedOnItems(list);

所提到的类只会为所有项目返回一个静态值,即使在某些情况下高度可能会有所不同,因为项目内的 TextView 的文本可能有两行或更多行。

item_bil.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="horizontal"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:background="?android:attr/activatedBackgroundIndicator"
              android:padding="10dp"
              android:weightSum="1">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="0.9"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginBottom="5dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/number"
                android:layout_marginEnd="2dp"
                android:textSize="12sp"/>

            <TextView
                android:id="@+id/number"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="{{number}}"
                android:textSize="12sp"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/hour"
                android:layout_marginStart="@dimen/activity_horizontal_margin"
                android:layout_marginEnd="2dp"
                android:textSize="12sp"/>

            <TextView
                android:id="@+id/hour"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="{{hour}}"
                android:textSize="12sp"/>

        </LinearLayout>

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="{{name}}"
            android:textSize="16sp"
            android:textColor="@color/colorPrimary"
            android:layout_marginBottom="5dp"
            android:gravity="center_vertical"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginBottom="5dp">

            <TextView
                android:id="@+id/address"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="{{address}}"
                android:textStyle="bold"
                android:textSize="12sp"
                android:gravity="center_vertical"/>

        </LinearLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="0.1">

        <TextView
            android:id="@+id/amount"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="{{amount}}"
            android:textSize="18sp"
            android:gravity="right"/>

    </LinearLayout>

</LinearLayout>

列表视图:

<ListView
    android:id="@+id/charges"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scrollbars="none"/>

【问题讨论】:

  • 您能详细解释一下为什么要以编程方式而不是在布局文件中设置列表视图高度吗?使用RelativeLayout,您可以放置​​所有视图并为列表视图提供所需的空间。如果布局中只有列表视图,则只需将其高度设置为match_parent
  • @PrasadPawar 那是因为我在 CardView 里面有那个 ListView,它同时在 ScrollView 里面。
  • 那么你为什么不使用垂直LinearLayout? Android 不建议在滚动视图中添加列表视图。即使你克服了这一点,你也会面临新的问题。如果你愿意,我可以发布一个小 sn-p 来证明我在说什么。
  • @PrasadPawar 我正在使用一个,抱歉我没有提到。实际的层次结构是:ScrollView > LinearLayout (vertical) > CardView > ListView
  • 很抱歉,整个结构似乎规划不佳。从它看起来你可以使用。一个列表视图作为根视图。然后列表项可以是您的卡片视图。卡片视图可以包含以垂直线性布局堆叠的所有视图。同样,如果您将任何可滚动视图嵌套在滚动视图中,则说明您做错了。

标签: android listview textview


【解决方案1】:

试试这个代码。它在我的应用程序中运行良好。

import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.ListView;

 /**
 * Created by Zohaib Hassan on 5/25/2015.
 */
public class ListviewHelper {

public static void getListViewSize(ListView myListView) {
    ListAdapter myListAdapter = myListView.getAdapter();
    if (myListAdapter == null) {
        //do nothing return null
        return;
    }
    //set listAdapter in loop for getting final size
    int totalHeight = 0;
    for (int size = 0; size < myListAdapter.getCount(); size++) {
        View listItem = myListAdapter.getView(size, null, myListView);
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }
    //setting listview item in adapter
    ViewGroup.LayoutParams params = myListView.getLayoutParams();
    View listItem = myListAdapter.getView(myListAdapter.getCount() - 1, null, myListView);
    listItem.measure(0, 0);
    params.height = totalHeight +  10
            + (myListView.getDividerHeight() * (myListAdapter.getCount() - 1));
    myListView.setLayoutParams(params);
    // print height of adapter on log
    Log.i("height of listItem:", String.valueOf(totalHeight));
}




}

还有另一件事可能会导致问题,请同时查看该问题。请确保您的屏幕在滚动之前至少完全显示列表视图的一项。否则,您最后一项列表的某些部分将被隐藏。如果是这种情况,那么您必须在“ListViewHelper”类的总高度中添加一个静态值。比方说:

params.height = totalHeight +  10 + 100
        + (myListView.getDividerHeight() * (myListAdapter.getCount() - 1));

希望这会有所帮助!

【讨论】:

  • 我试过了,但没有成功。我注意到的一件事是 listItem.getMeasuredHeight() 将始终为每个项目返回相同的值,这与我在原始实现中遇到的问题相同并且不正确,因为由于 TextView 并非所有项目都与我提到的高度相同动态行号。
  • 那么在这种情况下,在“ListViewHelper”中,您将一一获取列表中的所有项目;只需从“ListViewItem”中获取“TextView”并计算它的高度;然后在“总高度”中添加每个项目的高度。
  • 可以这样计算文本视图的高度:stackoverflow.com/questions/24359538/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-27
相关资源
最近更新 更多