我到处寻找这个问题的解决方案,我能找到的唯一答案似乎是“不要把一个ListView放入一个ScrollView”。不过,我还没有看到任何真正的解释。我能找到的唯一原因似乎是谷歌认为你不应该这么做。我知道,所以我做了。
问题是,如何将ListView放到ScrollView中而不缩到最小高度?
我到处寻找这个问题的解决方案,我能找到的唯一答案似乎是“不要把一个ListView放入一个ScrollView”。不过,我还没有看到任何真正的解释。我能找到的唯一原因似乎是谷歌认为你不应该这么做。我知道,所以我做了。
问题是,如何将ListView放到ScrollView中而不缩到最小高度?
当前回答
我把@DougW的实用程序转换成c#(在Xamarin中使用)。下面的代码对于列表中固定高度的项目很有效,如果只有一些项目比标准项目稍大一点,那么大多数项目都将很好,或者至少是一个良好的开端。
// You will need to put this Utility class into a code file including various
// libraries, I found that I needed at least System, Linq, Android.Views and
// Android.Widget.
using System;
using System.Linq;
using Android.Views;
using Android.Widget;
namespace UtilityNamespace // whatever you like, obviously!
{
public class Utility
{
public static void setListViewHeightBasedOnChildren (ListView listView)
{
if (listView.Adapter == null) {
// pre-condition
return;
}
int totalHeight = listView.PaddingTop + listView.PaddingBottom;
for (int i = 0; i < listView.Count; i++) {
View listItem = listView.Adapter.GetView (i, null, listView);
if (listItem.GetType () == typeof(ViewGroup)) {
listItem.LayoutParameters = new LinearLayout.LayoutParams (ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent);
}
listItem.Measure (0, 0);
totalHeight += listItem.MeasuredHeight;
}
listView.LayoutParameters.Height = totalHeight + (listView.DividerHeight * (listView.Count - 1));
}
}
}
谢谢@DougW,当我不得不使用其他人的代码时,这让我摆脱了困境。: -)
其他回答
在很多情况下,在ScrollView中有ListView是很有意义的。
下面是基于DougW建议的代码…工作在一个片段,占用较少的内存。
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
int totalHeight = 0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, listView);
if (i == 0) {
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, LayoutParams.WRAP_CONTENT));
}
view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
在每个嵌入的列表视图上调用setListViewHeightBasedOnChildren(listview)。
你不应该把ListView放到ScrollView中因为ListView已经是一个ScrollView了。这就像把一个ScrollView放到一个ScrollView中。
你想要完成什么?
不要在scrollview中使用listview。相反,你应该使用NestedScrollView作为父视图,并在....中使用RecyclerView因为它处理了很多滚动问题
我使用的一个解决方案是,添加ScrollView的所有内容(应该在listView的上面和下面)作为listView中的headerView和footerView。
它的工作原理是,convertview按它应该的方式重新使用。
这是DougW、Good Guy Greg和Paul的答案组合。我发现当尝试使用自定义列表视图适配器和非标准列表项时,这都是需要的,否则列表视图会导致应用程序崩溃(也会导致Nex的答案崩溃):
public void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom();
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
if (listItem instanceof ViewGroup)
listItem.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}