我到处寻找这个问题的解决方案,我能找到的唯一答案似乎是“不要把一个ListView放入一个ScrollView”。不过,我还没有看到任何真正的解释。我能找到的唯一原因似乎是谷歌认为你不应该这么做。我知道,所以我做了。

问题是,如何将ListView放到ScrollView中而不缩到最小高度?


当前回答

这些答案都是错的!! 如果你想把一个列表视图放在滚动视图中,你应该重新考虑你的设计。你试图把一个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;
    }


}

列表适配器可以处理所有内容,因为它只呈现可见的内容。

其他回答

我们可以将ListView用作ScrollView,而不是将ListView放在ScrollView中。必须在ListView中的东西可以放到ListView中。在ListView的顶部和底部的其他布局可以通过添加布局到ListView的页眉和页脚。整个ListView会给你滚动的体验。

感谢Vinay的代码,这是我的代码,当你不能在滚动视图中有一个列表视图时,你需要这样的东西

LayoutInflater li = LayoutInflater.from(this);

                RelativeLayout parent = (RelativeLayout) this.findViewById(R.id.relativeLayoutCliente);

                int recent = 0;

                for(Contatto contatto : contatti)
                {
                    View inflated_layout = li.inflate(R.layout.header_listview_contatti, layout, false);


                    inflated_layout.setId(contatto.getId());
                    ((TextView)inflated_layout.findViewById(R.id.textViewDescrizione)).setText(contatto.getDescrizione());
                    ((TextView)inflated_layout.findViewById(R.id.textViewIndirizzo)).setText(contatto.getIndirizzo());
                    ((TextView)inflated_layout.findViewById(R.id.textViewTelefono)).setText(contatto.getTelefono());
                    ((TextView)inflated_layout.findViewById(R.id.textViewMobile)).setText(contatto.getMobile());
                    ((TextView)inflated_layout.findViewById(R.id.textViewFax)).setText(contatto.getFax());
                    ((TextView)inflated_layout.findViewById(R.id.textViewEmail)).setText(contatto.getEmail());



                    RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);

                    if (recent == 0)
                    {
                        relativeParams.addRule(RelativeLayout.BELOW, R.id.headerListViewContatti);
                    }
                    else
                    {
                        relativeParams.addRule(RelativeLayout.BELOW, recent);
                    }
                    recent = inflated_layout.getId();

                    inflated_layout.setLayoutParams(relativeParams);
                    //inflated_layout.setLayoutParams( new RelativeLayout.LayoutParams(source));

                    parent.addView(inflated_layout);
                }

relativeLayout保持在ScrollView中,所以它都是可滚动的:)

当我们把ListView放在ScrollView里面时,会出现两个问题。一个是ScrollView测量它的子在未指定的模式,所以ListView设置自己的高度,只容纳一个项目(我不知道为什么),另一个是ScrollView拦截触摸事件,所以ListView不滚动。

但我们可以把ListView放到ScrollView里面。这篇文章是我写的,解释了解决办法。通过这个解决方案,我们还可以保留ListView的回收功能。

这是唯一对我有效的方法:

你可以在棒棒糖上使用

yourtListView.setNestedScrollingEnabled(true);

这将启用或禁用此视图的嵌套滚动 如果你需要向后兼容旧版本的操作系统,你必须使用RecyclerView。

在ScrollView中使用ListView有两个问题。

ListView必须完全展开到它的子节点高度。这个ListView解决这个问题:

public class ListViewExpanded extends ListView
{
    public ListViewExpanded(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        setDividerHeight(0);
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST));
    }
}

分隔高度必须为0,在行中使用填充代替。

2- ListView消耗触摸事件,所以ScrollView不能像往常一样滚动。这个ScrollView解决了这个问题:

public class ScrollViewInterceptor extends ScrollView
{
    float startY;

    public ScrollViewInterceptor(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e)
    {
        onTouchEvent(e);
        if (e.getAction() == MotionEvent.ACTION_DOWN) startY = e.getY();
        return (e.getAction() == MotionEvent.ACTION_MOVE) && (Math.abs(startY - e.getY()) > 50);
    }
}

这是我发现的最好的方法!