我到处寻找这个问题的解决方案,我能找到的唯一答案似乎是“不要把一个ListView放入一个ScrollView”。不过,我还没有看到任何真正的解释。我能找到的唯一原因似乎是谷歌认为你不应该这么做。我知道,所以我做了。
问题是,如何将ListView放到ScrollView中而不缩到最小高度?
我到处寻找这个问题的解决方案,我能找到的唯一答案似乎是“不要把一个ListView放入一个ScrollView”。不过,我还没有看到任何真正的解释。我能找到的唯一原因似乎是谷歌认为你不应该这么做。我知道,所以我做了。
问题是,如何将ListView放到ScrollView中而不缩到最小高度?
当前回答
我们可以将ListView用作ScrollView,而不是将ListView放在ScrollView中。必须在ListView中的东西可以放到ListView中。在ListView的顶部和底部的其他布局可以通过添加布局到ListView的页眉和页脚。整个ListView会给你滚动的体验。
其他回答
这些答案都是错的!! 如果你想把一个列表视图放在滚动视图中,你应该重新考虑你的设计。你试图把一个ScrollView放到一个ScrollView中。干扰列表将损害列表性能。Android就是这样设计的。
如果你真的想让列表和其他元素在同一个滚动中,你所要做的就是在适配器中使用一个简单的switch语句将其他项添加到列表的顶部:
class MyAdapter extends ArrayAdapter{
public MyAdapter(Context context, int resource, List objects) {
super(context, resource, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewItem viewType = getItem(position);
switch(viewType.type){
case TEXTVIEW:
convertView = layouteInflater.inflate(R.layout.textView1, parent, false);
break;
case LISTITEM:
convertView = layouteInflater.inflate(R.layout.listItem, parent, false);
break; }
return convertView;
}
}
列表适配器可以处理所有内容,因为它只呈现可见的内容。
以下是对@djunod的回答的小修改,我需要使它完美地工作:
public static void setListViewHeightBasedOnChildren(ListView listView)
{
ListAdapter listAdapter = listView.getAdapter();
if(listAdapter == null) return;
if(listAdapter.getCount() <= 1) 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);
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();
}
我把@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 ></ScrollView>在布局XML文件与这个自定义ScrollView像<com.tmd.utils。VerticalScrollview > </com.tmd.utils。VerticalScrollview >
package com.tmd.utils;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ScrollView;
public class VerticalScrollview extends ScrollView{
public VerticalScrollview(Context context) {
super(context);
}
public VerticalScrollview(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VerticalScrollview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.i("VerticalScrollview", "onInterceptTouchEvent: DOWN super false" );
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_MOVE:
return false; // redirect MotionEvents to ourself
case MotionEvent.ACTION_CANCEL:
Log.i("VerticalScrollview", "onInterceptTouchEvent: CANCEL super false" );
super.onTouchEvent(ev);
break;
case MotionEvent.ACTION_UP:
Log.i("VerticalScrollview", "onInterceptTouchEvent: UP super false" );
return false;
default: Log.i("VerticalScrollview", "onInterceptTouchEvent: " + action ); break;
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
Log.i("VerticalScrollview", "onTouchEvent. action: " + ev.getAction() );
return true;
}
}
使用ListView来使它不滚动是非常昂贵的,并且违背了ListView的整个目的。你不应该这样做。只是使用线性布局代替。