如何在不折叠的情况下将ListView放入ScrollView?

时间:2010-08-16 18:00:58

标签: android android-listview android-scrollview

我一直在寻找这个问题的解决方案,我能找到的唯一答案似乎是“don't put a ListView into a ScrollView”。我还没有看到为什么的任何真实解释。我似乎找到的唯一原因是Google认为你不应该这样做。好吧,我做了,所以我做了。

所以问题是,如何将ListView放入ScrollView而不将其折叠到最小高度?

28 个答案:

答案 0 :(得分:258)

这是我的解决方案。我是Android平台的新手,我确信这有点hackish,特别是关于直接调用.measure的部分,直接设置LayoutParams.height属性,但它有效。

您所要做的就是致电Utility.setListViewHeightBasedOnChildren(yourListView),它会调整大小以准确容纳其物品的高度。

public class Utility {
    public static void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            // pre-condition
            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);
    }
}

答案 1 :(得分:192)

使用ListView使其不滚动非常昂贵,并且违背了ListView的全部目的。你应该这样做。只需使用LinearLayout代替。

答案 2 :(得分:89)

这肯定有效............
您必须使用此<ScrollView ></ScrollView>替换布局XML文件中的Custom 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;
    }
}

答案 3 :(得分:24)

ListView置于ScrollView内,我们可以将ListView用作ScrollView。必须在ListView中的内容可以放在ListView内。可以通过向ListView的页眉和页脚添加布局来放置ListView顶部和底部的其他布局。因此整个ListView将为您提供滚动体验。

答案 4 :(得分:21)

很多的情况下,在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)。

答案 5 :(得分:16)

ListView实际上已经能够测量自身足够高以显示所有项目,但是当您只是指定wrap_content(MeasureSpec.UNSPECIFIED)时它不会这样做。当使用MeasureSpec.AT_MOST给出高度时,它将执行此操作。有了这些知识,您可以创建一个非常简单的子类来解决这个问题,它比上面发布的任何解决方案都要好得多。你应该仍然在这个子类中使用wrap_content。

public class ListViewForEmbeddingInScrollView extends ListView {
    public ListViewForEmbeddingInScrollView(Context context) {
        super(context);
    }

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

    public ListViewForEmbeddingInScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

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

使用非常大的大小(Integer.MAX_VALUE&gt;&gt; 4)操作heightMeasureSpec为AT_MOST会导致ListView测量其所有子节点,直到给定(非常大)的高度并相应地设置其高度。

由于以下几个原因,这比其他解决方案效果更好:

  1. 它正确测量一切(填充,分隔)
  2. 在度量传递期间测量ListView
  3. 由于#2,它可以正确处理项目宽度或数量的变化而无需任何其他代码
  4. 在缺点方面,您可能会认为这样做依赖于SDK中可能发生变化的无证行为。另一方面,您可能会认为这就是wrap_content应该如何与ListView一起使用,并且当前的wrap_content行为刚刚被破坏。

    如果你担心将来会改变这种行为,你应该简单地将onMeasure函数和相关函数从ListView.java复制到你自己的子类中,然后通过onMeasure运行AT_MOST路径同样。

    顺便说一句,我相信当你处理少量列表项时,这是一种非常有效的方法。与LinearLayout相比,它可能效率低,但当项目数量较少时,使用LinearLayout是不必要的优化,因此不必要的复杂性。

答案 6 :(得分:12)

有一个内置的设置。在ScrollView上:

android:fillViewport="true"

在Java中,

mScrollView.setFillViewport(true);

Romain Guy在此深入解释:http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/

答案 7 :(得分:8)

您创建不可滚动的自定义ListView

public class NonScrollListView extends ListView {

    public NonScrollListView(Context context) {
        super(context);
    }
    public NonScrollListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public NonScrollListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
                    Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
            ViewGroup.LayoutParams params = getLayoutParams();
            params.height = getMeasuredHeight();    
    }
}

在您的布局资源文件

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <!-- com.Example Changed with your Package name -->

    <com.Example.NonScrollListView
        android:id="@+id/lv_nonscroll_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </com.Example.NonScrollListView>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/lv_nonscroll_list" >

        <!-- Your another layout in scroll view -->

    </RelativeLayout>
</RelativeLayout>

在Java文件中

创建customListview的对象而不是ListView,如: NonScrollListView non_scroll_list =(NonScrollListView)findViewById(R.id.lv_nonscroll_list);

答案 8 :(得分:8)

我们无法使用两个滚动simulteniuosly.We将获得ListView的总长度并使用总高度扩展listview。然后我们可以直接在ScrollView中添加ListView或使用LinearLayout,因为ScrollView直接有一个子节点。 在代码中复制setListViewHeightBasedOnChildren(lv)方法并展开listview,然后可以在scrollview中使用listview。 \ layout xml file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
 <ScrollView

        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
         android:background="#1D1D1D"
        android:orientation="vertical"
        android:scrollbars="none" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="#1D1D1D"
            android:orientation="vertical" >

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="40dip"
                android:background="#333"
                android:gravity="center_vertical"
                android:paddingLeft="8dip"
                android:text="First ListView"
                android:textColor="#C7C7C7"
                android:textSize="20sp" />

            <ListView
                android:id="@+id/first_listview"
                android:layout_width="260dp"
                android:layout_height="wrap_content"
                android:divider="#00000000"
               android:listSelector="#ff0000"
                android:scrollbars="none" />

               <TextView
                android:layout_width="fill_parent"
                android:layout_height="40dip"
                android:background="#333"
                android:gravity="center_vertical"
                android:paddingLeft="8dip"
                android:text="Second ListView"
                android:textColor="#C7C7C7"
                android:textSize="20sp" />

            <ListView
                android:id="@+id/secondList"
                android:layout_width="260dp"
                android:layout_height="wrap_content"
                android:divider="#00000000"
                android:listSelector="#ffcc00"
                android:scrollbars="none" />
  </LinearLayout>
  </ScrollView>

   </LinearLayout>

Activity类中的onCreate方法:

 import java.util.ArrayList;
  import android.app.Activity;
 import android.os.Bundle;
 import android.view.Menu;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
 import android.widget.ListAdapter;
  import android.widget.ListView;

   public class MainActivity extends Activity {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.listview_inside_scrollview);
    ListView list_first=(ListView) findViewById(R.id.first_listview);
    ListView list_second=(ListView) findViewById(R.id.secondList);
    ArrayList<String> list=new ArrayList<String>();
    for(int x=0;x<30;x++)
    {
        list.add("Item "+x);
    }

       ArrayAdapter<String> adapter=new ArrayAdapter<String>(getApplicationContext(), 
          android.R.layout.simple_list_item_1,list);               
      list_first.setAdapter(adapter);

     setListViewHeightBasedOnChildren(list_first);

      list_second.setAdapter(adapter);

    setListViewHeightBasedOnChildren(list_second);
   }



   public static void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null) {
        // pre-condition
        return;
    }

    int totalHeight = 0;
    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);
        listItem.measure(0, 0);
        totalHeight += listItem.getMeasuredHeight();
    }

    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight
            + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    listView.setLayoutParams(params);
      }

答案 9 :(得分:4)

这是DougW,Good Guy Greg和Paul的答案的组合。我发现在尝试使用自定义列表视图适配器和非标准列表项时都需要它,否则listview会崩溃应用程序(也会被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);
    }

答案 10 :(得分:3)

我将@ DougW&#39; s Utility转换为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,当我不得不与OtherPeople的代码合作时,这让我摆脱了困境。 : - )

答案 11 :(得分:3)

您不应该将ListView放在ScrollView中,因为已经的ListView 是ScrollView。这就像把ScrollView放在ScrollView中一样。

你想要完成什么?

答案 12 :(得分:2)

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

1- 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);
    }
}

这是我发现的最佳方法!

答案 13 :(得分:2)

这是唯一对我有用的东西:

在Lollipop之后你可以使用

yourtListView.setNestedScrollingEnabled(true);

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

答案 14 :(得分:2)

我使用的解决方案是将所有ScrollView内容(应该在listView上面和下面的内容)添加为ListView中的headerView和footerView。

所以它的工作原理,转换视图也应该如何恢复。

答案 15 :(得分:2)

嘿我有类似的问题。我想显示一个没有滚动的列表视图,我发现操作参数工作但效率低,并且在不同的设备上表现不同..因此,这是我的计划代码的一部分,实际上非常有效地执行此操作

db = new dbhelper(this);

 cursor = db.dbCursor();
int count = cursor.getCount();
if (count > 0)
{    
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.layoutId);
startManagingCursor(YOUR_CURSOR);

YOUR_ADAPTER(**or SimpleCursorAdapter **) adapter = new YOUR_ADAPTER(this,
    R.layout.itemLayout, cursor, arrayOrWhatever, R.id.textViewId,
    this.getApplication());

int i;
for (i = 0; i < count; i++){
  View listItem = adapter.getView(i,null,null);
  linearLayout.addView(listItem);
   }
}

注意:如果您使用此功能,notifyDataSetChanged();将无法按预期工作,因为视图不会重绘。 如果您需要解决方法,请执行此操作

adapter.registerDataSetObserver(new DataSetObserver() {

            @Override
            public void onChanged() {
                super.onChanged();
                removeAndRedrawViews();

            }

        });

答案 16 :(得分:1)

试试这个,这对我有用,我忘了我发现它的地方,堆栈溢出的地方, 我不是来解释为什么它不起作用,但这就是答案:)。

    final ListView AturIsiPulsaDataIsiPulsa = (ListView) findViewById(R.id.listAturIsiPulsaDataIsiPulsa);
    AturIsiPulsaDataIsiPulsa.setOnTouchListener(new ListView.OnTouchListener() 
    {
        @Override
        public boolean onTouch(View v, MotionEvent event) 
        {
            int action = event.getAction();
            switch (action) 
            {
                case MotionEvent.ACTION_DOWN:
                // Disallow ScrollView to intercept touch events.
                v.getParent().requestDisallowInterceptTouchEvent(true);
                break;

                case MotionEvent.ACTION_UP:
                // Allow ScrollView to intercept touch events.
                v.getParent().requestDisallowInterceptTouchEvent(false);
                break;
            }

            // Handle ListView touch events.
            v.onTouchEvent(event);
            return true;
        }
    });
    AturIsiPulsaDataIsiPulsa.setClickable(true);
    AturIsiPulsaDataIsiPulsa.setAdapter(AturIsiPulsaDataIsiPulsaAdapter);

编辑!,我终于找到了我得到代码的地方。这里 ! :ListView inside ScrollView is not scrolling on Android

答案 17 :(得分:1)

尽管建议的 setListViewHeightBasedOnChildren()方法适用于大多数情况,但在某些情况下,特别是对很多项目,我注意到最后的元素没有显示。所以我决定模仿 ListView 行为的简单版本,以便重用任何适配器代码,这里是ListView替代方案:

import android.content.Context;
import android.database.DataSetObserver;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ListAdapter;

public class StretchedListView extends LinearLayout {

private final DataSetObserver dataSetObserver;
private ListAdapter adapter;
private OnItemClickListener onItemClickListener;

public StretchedListView(Context context, AttributeSet attrs) {
    super(context, attrs);
    setOrientation(LinearLayout.VERTICAL);
    this.dataSetObserver = new DataSetObserver() {
        @Override
        public void onChanged() {
            syncDataFromAdapter();
            super.onChanged();
        }

        @Override
        public void onInvalidated() {
            syncDataFromAdapter();
            super.onInvalidated();
        }
    };
}

public void setAdapter(ListAdapter adapter) {
    ensureDataSetObserverIsUnregistered();

    this.adapter = adapter;
    if (this.adapter != null) {
        this.adapter.registerDataSetObserver(dataSetObserver);
    }
    syncDataFromAdapter();
}

protected void ensureDataSetObserverIsUnregistered() {
    if (this.adapter != null) {
        this.adapter.unregisterDataSetObserver(dataSetObserver);
    }
}

public Object getItemAtPosition(int position) {
    return adapter != null ? adapter.getItem(position) : null;
}

public void setSelection(int i) {
    getChildAt(i).setSelected(true);
}

public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
    this.onItemClickListener = onItemClickListener;
}

public ListAdapter getAdapter() {
    return adapter;
}

public int getCount() {
    return adapter != null ? adapter.getCount() : 0;
}

private void syncDataFromAdapter() {
    removeAllViews();
    if (adapter != null) {
        int count = adapter.getCount();
        for (int i = 0; i < count; i++) {
            View view = adapter.getView(i, null, this);
            boolean enabled = adapter.isEnabled(i);
            if (enabled) {
                final int position = i;
                final long id = adapter.getItemId(position);
                view.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        if (onItemClickListener != null) {
                            onItemClickListener.onItemClick(null, v, position, id);
                        }
                    }
                });
            }
            addView(view);

        }
    }
}
}

答案 18 :(得分:1)

以下是@djunodanswer的小修改,我需要让它完美运行:

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();
}

答案 19 :(得分:1)

所有这些答案都是错误的! 如果您尝试将列表视图放在滚动视图中,则应重新考虑您的设计。您正在尝试将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;
    }


}

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

答案 20 :(得分:1)

感谢Vinay's code这里是我的代码,当你在滚动视图中没有列表视图但你需要类似的东西时

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中,因此它们都可以滚动:)

答案 21 :(得分:1)

之前不可能。但随着新的Appcompat库和设计库的发布,这可以实现。

您只需使用NestedScrollView https://developer.android.com/reference/android/support/v4/widget/NestedScrollView.html

我不知道它是否适用于Listview,但与RecyclerView配合使用。

代码段:

<android.support.v4.widget.NestedScrollView 
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

</android.support.v4.widget.NestedScrollView>

答案 22 :(得分:0)

当我们在ListView内放置ScrollView时,会出现两个问题。一个是ScrollView在非正式模式下测量其子项,因此ListView设置自己的高度以仅容纳一个项目(我不知道为什么),另一个是ScrollView拦截触摸因此事件ListView不会滚动。

但我们可以ListView置于ScrollView内并采取一些解决方法。我This post解释了解决方法。通过此解决方法,我们还可以保留ListView的回收功能。

答案 23 :(得分:0)

如果LinearLayout有一个setAdapter方法,整个问题就会消失,因为当你告诉别人使用它时,替代方案将是微不足道的。

如果你真的想要在另一个滚动视图中滚动ListView,这不会有帮助,但除此之外,这至少会给你一个想法。

您需要创建一个自定义适配器,以组合您要滚动的所有内容,并将ListView的适配器设置为该适配器。

我没有方便的示例代码,但是如果你想要类似的东西。

<ListView/>

(other content)

<ListView/>

然后,您需要创建一个表示所有内容的适配器。 ListView / Adapters足够智能,可以处理不同的类型,但您需要自己编写适配器。

Android UI API并不像其他所有其他平台一样成熟,因此它与其他平台没有相同的细节。此外,当你在Android上做某事时,你需要处于一个android(unix)思维模式,在那里你希望做任何事情你可能需要组装较小部分的功能并编写一堆你自己的代码来获取它起作用。

答案 24 :(得分:0)

不是将listview放在Scrollview中,而是将listview和Scrollview的开头之间的其余内容作为单独的视图放置,并将该视图设置为listview的标题。因此,您最终只会查看负责Scroll的列表视图。

答案 25 :(得分:0)

This库是解决问题的最简单,最快捷的解决方案。

答案 26 :(得分:0)

您永远不应该在 listview 中使用 scrollview。相反,您应该在其中使用 NestedScrollView 作为父级和 RecyclerView ......因为它处理了很多滚动问题

答案 27 :(得分:-1)

这是我的代码版本,用于计算列表视图的总高度。这个对我有用:

   public static void setListViewHeightBasedOnChildren(ListView listView) {
    ListAdapter listAdapter = listView.getAdapter();
    if (listAdapter == null || listAdapter.getCount() < 2) {
        // pre-condition
        return;
    }

    int totalHeight = 0;
    int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(BCTDApp.getDisplaySize().width, View.MeasureSpec.AT_MOST);
    int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
    ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

    for (int i = 0; i < listAdapter.getCount(); i++) {
        View listItem = listAdapter.getView(i, null, listView);
        if (listItem instanceof ViewGroup) listItem.setLayoutParams(lp);
        listItem.measure(widthMeasureSpec, heightMeasureSpec);
        totalHeight += listItem.getMeasuredHeight();
    }

    totalHeight += listView.getPaddingTop() + listView.getPaddingBottom();
    totalHeight += (listView.getDividerHeight() * (listAdapter.getCount() - 1));
    ViewGroup.LayoutParams params = listView.getLayoutParams();
    params.height = totalHeight;
    listView.setLayoutParams(params);
    listView.requestLayout();
}