358

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

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

4

28 回答 28

263

这是我的解决方案。我对 Android 平台相当陌生,我敢肯定这有点骇人听闻,尤其是在有关直接调用 .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);
    }
}
于 2010-08-16T18:04:16.787 回答
198

使用 aListView使其不滚动非常昂贵,并且违背了ListView. 你不应该这样做。只需使用 aLinearLayout代替。

于 2010-08-16T18:19:48.733 回答
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;
    }
}
于 2012-12-10T06:40:39.933 回答
25

Insted 放入ListViewaScrollView中,我们可以ListView用作 a ScrollView。必须放入的东西ListView可以放在里面ListView。顶部和底部的其他布局ListView可以通过在页眉和页脚中添加布局来放置ListView。所以整体ListView会给你一种滚动的体验。

于 2012-12-31T12:50:13.543 回答
21

很多情况下,将 ListView 放在 ScrollView 中是很有意义的。

这是基于 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)。

于 2013-07-20T18:46:49.857 回答
17

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

将 heightMeasureSpec 操作为具有非常大尺寸 (Integer.MAX_VALUE >> 4) 的 AT_MOST 会导致 ListView 测量其所有子级直到给定(非常大)高度并相应地设置其高度。

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

  1. 它可以正确测量所有内容(填充,分隔线)
  2. 它在测量过程中测量 ListView
  3. 由于#2,它可以正确处理宽度或项目数量的变化,而无需任何额外的代码

不利的一面是,您可能会争辩说这样做依赖于 SDK 中可能会改变的未记录行为。另一方面,您可能会争辩说这是 wrap_content 应该如何真正与 ListView 一起工作,并且当前的 wrap_content 行为被破坏了。

如果您担心将来行为会发生变化,您应该简单地将 onMeasure 函数和相关函数从 ListView.java 复制到您自己的子类中,然后通过 onMeasure 的 AT_MOST 路径也为 UNSPECIFIED 运行。

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

于 2015-04-17T20:01:25.983 回答
13

它有一个内置设置。在滚动视图上:

android:fillViewport="true"

在 Java 中,

mScrollView.setFillViewport(true);

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

于 2014-08-04T05:50:14.580 回答
10

您创建不可滚动的自定义 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);

于 2016-05-24T10:28:39.147 回答
8

We could not use two scrolling simulteniuosly.We will have get total length of ListView and expand listview with the total height .Then we can add ListView in ScrollView directly or using LinearLayout because ScrollView have directly one child . copy setListViewHeightBasedOnChildren(lv) method in your code and expand listview then you can use listview inside scrollview. \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>

onCreate method in Activity class:

 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);
      }
于 2014-07-12T06:37:49.617 回答
6

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

从 Lollipop 开始,您可以使用

yourtListView.setNestedScrollingEnabled(true);

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

于 2016-11-07T07:30:27.730 回答
4

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

你想达到什么目的?

于 2010-08-16T18:02:45.290 回答
4

这是 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);
    }
于 2013-08-04T19:29:25.030 回答
3

我将@DougW 转换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'sCode 时,这让我摆脱了困境。:-)

于 2014-07-09T04:31:51.393 回答
3

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

你只需要使用 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>
于 2017-10-10T05:25:33.170 回答
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);
    }
}

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

于 2014-03-31T00:37:21.413 回答
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();

            }

        });
于 2012-05-11T15:59:22.933 回答
2

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

所以它的工作原理是,convertview 也应该是这样。

于 2015-07-24T07:52:01.107 回答
1

虽然建议的setListViewHeightBasedOnChildren()方法在大多数情况下都有效,但在某些情况下,特别是对于很多项目,我注意到最后一个元素没有显示。所以我决定模仿ListView行为的一个简单版本,以便重用任何 Adapter 代码,这里是 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);

        }
    }
}
}
于 2014-02-19T11:08:08.260 回答
1

这是对@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();
}
于 2013-09-23T18:39:06.737 回答
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);

编辑!,我终于找到了我得到代码的地方。这里 !: ScrollView 中的 ListView 在 Android 上不滚动

于 2014-03-03T03:51:27.183 回答
1

感谢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 内,因此它全部变为可滚动的 :)

于 2012-06-22T14:01:55.960 回答
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;
    }


}

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

于 2016-02-10T20:56:27.360 回答
0

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

如果您真的想要在另一个滚动视图中滚动 ListView,这将无济于事,否则这至少会给您一个想法。

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

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

<ListView/>

(other content)

<ListView/>

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

android UI API 并没有其他平台那么成熟,所以它没有其他平台那么好。此外,在 android 上做某事时,您需要处于 android (unix) 思维模式,在这种思维模式下,您希望做任何事情,您可能必须组装较小部分的功能并编写一堆您自己的代码来实现它工作。

于 2013-01-13T19:41:41.227 回答
0

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

但是我们可以通过一些解决方法将其放置ListView在内部。我的这篇文章解释了解决方法。通过这种解决方法,我们还可以保留的回收功能。ScrollViewListView

于 2014-10-24T04:36:43.907 回答
0

与其将 listview 放在 Scrollview 中,不如将 listview 和 Scrollview 的打开之间的其余内容作为单独的视图,并将该视图设置为 listview 的标题。所以你最终将只负责 Scroll 的列表视图。

于 2016-03-14T14:55:30.387 回答
0

这个库是解决这个问题的最简单和最快的方法。

于 2017-01-25T02:31:29.193 回答
0

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

于 2021-01-31T09:08:40.917 回答
-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();
}
于 2014-02-13T23:15:46.600 回答