【发布时间】: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
-
很抱歉,整个结构似乎规划不佳。从它看起来你可以使用。一个列表视图作为根视图。然后列表项可以是您的卡片视图。卡片视图可以包含以垂直线性布局堆叠的所有视图。同样,如果您将任何可滚动视图嵌套在滚动视图中,则说明您做错了。