我一直在寻找这个问题的解决方案,我能找到的唯一答案似乎是“don't put a ListView into a ScrollView” . 我还没有看到任何真正的解释为什么 . 我似乎找到的唯一原因是Google认为你不应该这样做 . 好吧,我做了,所以我做到了 .
所以问题是,如何将ListView放入ScrollView而不将其折叠到最小高度?
我一直在寻找这个问题的解决方案,我能找到的唯一答案似乎是“don't put a ListView into a ScrollView” . 我还没有看到任何真正的解释为什么 . 我似乎找到的唯一原因是Google认为你不应该这样做 . 好吧,我做了,所以我做到了 .
所以问题是,如何将ListView放入ScrollView而不将其折叠到最小高度?
27 回答
This库是解决该问题的最简单,最快捷的解决方案 .
使用
ListView
使其不滚动是非常昂贵的,并违背ListView
的整个目的 . 你应该 NOT 这样做 . 只需使用LinearLayout
.这里's my solution. I'对于Android平台来说相当新,我确信这有点hackish,特别是关于直接调用.measure并直接设置
LayoutParams.height
属性的部分,但是它有效 .您所要做的就是调用
Utility.setListViewHeightBasedOnChildren(yourListView)
,它将调整大小以准确容纳其项目的高度 .This will definitely work............
你必须用
Custom ScrollView
替换<ScrollView ></ScrollView>
布局XML文件,如<com.tmd.utils.VerticalScrollview > </com.tmd.utils.VerticalScrollview >
如果将
ListView
放在ScrollView
中,我们可以使用ListView
作为ScrollView
. 必须在ListView
中的东西可以放在ListView
内 . 通过在ListView
的页眉和页脚中添加布局,可以放置ListView
顶部和底部的其他布局 . 因此整个ListView
将为您提供滚动体验 .在很多情况下,在ScrollView中使用ListView非常有意义 .
这里的代码基于DougW的建议......在片段中工作,占用更少的内存 .
在每个嵌入式列表视图上调用setListViewHeightBasedOnChildren(listview) .
ListView实际上已经能够测量自身足够高以显示所有项目,但是当您只是指定wrap_content(MeasureSpec.UNSPECIFIED)时它不会这样做 . 当使用MeasureSpec.AT_MOST给出高度时,它将执行此操作 . 有了这些知识,你可以创建一个非常简单的子类来解决这个问题,它比上面发布的任何解决方案都要好得多 . 你应该仍然在这个子类中使用wrap_content .
将heightMeasureSpec操作为具有非常大的AT_MOST(Integer.MAX_VALUE >> 4)会导致ListView测量其所有子节点到达给定(非常大)的高度并相应地设置其高度 .
由于以下几个原因,这比其他解决方案效果更好:
它正确测量一切(填充,分隔)
它在度量过程中测量ListView
由于#2,它无需任何额外代码即可正确处理项目宽度或数量的变化
在缺点方面,您可能会认为这样做依赖于SDK中可能发生变化的无证行为 . 另一方面,您可能会认为这就是wrap_content应该如何与ListView一起使用,并且当前的wrap_content行为刚刚被破坏 .
如果你担心将来会改变这种行为,你应该简单地将onMeasure函数和相关函数从ListView.java复制到你自己的子类中,然后通过onMeasure运行AT_MOST路径也可以运行 .
顺便说一句,我相信当你处理少量列表项时,这是一种非常有效的方法 . 与LinearLayout相比,它可能效率低,但是当项目数量较少时,使用LinearLayout是不必要的优化,因此不必要的复杂性 .
它有一个内置的设置 . 在ScrollView上:
在Java中
Romain Guy在这里深入解释:http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/
我们不能使用两个滚动simulteniuosly . 我们将获得ListView的总长度并使用总高度扩展listview . 然后我们可以直接在ScrollView中添加ListView或使用LinearLayout,因为ScrollView直接有一个子节点 . 在代码中复制setListViewHeightBasedOnChildren(lv)方法并展开listview,然后可以在scrollview中使用listview . \ layout xml文件
Activity类中的onCreate方法:
您创建不可滚动的自定义ListView
在您的布局资源文件中
在Java文件中
创建customListview的对象而不是ListView,如:NonScrollListView non_scroll_list =(NonScrollListView)findViewById(R.id.lv_nonscroll_list);
这是DougW,Good Guy Greg和Paul的答案的组合 . 我发现在尝试使用自定义列表视图适配器和非标准列表项时都需要它,否则listview会崩溃应用程序(也会被Nex的答案崩溃):
我将@ DougW的
Utility
转换为C#(用于Xamarin) . 以下适用于列表中固定高度的项目,并且如果只有一些项目比标准项目稍大一些,那么大多数都会很好,或者至少是一个好的开始 .谢谢@DougW,当我不得不使用OtherPeople的代码时,这让我摆脱了困境 . :-)
您不应该将ListView放在ScrollView中,因为ListView已经是ScrollView . 这就像将ScrollView放在ScrollView中一样 .
你想达到什么目的?
嘿我有类似的问题 . 我想显示一个没有滚动的列表视图,我发现操作参数有效但效率低,并且在不同的设备上表现不同......因此,这是我的计划代码的一部分,实际上非常有效地执行此操作 .
注意:如果您使用此选项,
notifyDataSetChanged();
将无法正常工作,因为不会重绘视图 . 如果你需要一个解决方法,请这样做在ScrollView中使用ListView时有两个问题 .
1- ListView必须完全扩展到其子高度 . 这个ListView解决了这个问题:
分隔符高度必须为0,而是使用行中的填充 .
2- ListView使用触摸事件,因此无法像往常一样滚动ScrollView . 此ScrollView解决此问题:
这是我发现的最好方法!
This is the only thing that worked for me:
在棒棒糖上你可以使用
如果您需要向后兼容您必须使用RecyclerView的旧版操作系统,则启用或禁用此视图的嵌套滚动 .
感谢Vinay's code这里是我的代码,当你在滚动视图中没有列表视图但你需要类似的东西
relativeLayout保留在ScrollView中,所以它都变得可滚动了:)
这是对@djunod的answer的小修改,我需要让它完美地运作:
试试这个,这对我有用,我忘了我发现它的地方,堆栈溢出的地方,我不是在这里解释它为什么它不起作用,但这是答案:) .
编辑!,我终于找到了我得到代码的地方 . 这里 ! :ListView inside ScrollView is not scrolling on Android
虽然建议的 setListViewHeightBasedOnChildren() 方法适用于大多数情况,但在某些情况下,特别是有很多项目,我注意到最后的元素没有显示 . 所以我决定模仿 ListView 行为的简单版本,以便重用任何适配器代码,这里是ListView的替代方案:
我使用的解决方案是将ListView中的所有ScrollView内容(应该在listView上面和下面)添加为headerView和footerView .
所以它的工作原理,转换视图也应该如何重新启动 .
所有这些答案都是错误的!如果您尝试将列表视图放在滚动视图中,则应重新考虑您的设计 . 您正在尝试将ScrollView放入ScrollView中 . 干扰列表会损害列表性能 . Android的设计就是这样的 .
如果您确实希望列表与其他元素位于同一个滚动中,您只需使用适配器中的简单switch语句将其他项添加到列表顶部:
列表适配器可以处理所有内容,因为它只呈现可见内容 .
在它不可能之前 . 但随着新的Appcompat库和设计库的发布,这可以实现 .
你只需要使用NestedScrollView https://developer.android.com/reference/android/support/v4/widget/NestedScrollView.html
我不知道它是否适用于Listview,但与RecyclerView配合使用 .
代码片段:
如果LinearLayout有一个setAdapter方法,整个问题就会消失,因为当你告诉别人使用它时,替代方案将是微不足道的 .
如果你真的想要在另一个滚动视图中滚动ListView,这将无济于事,但除此之外,这至少会给你一个想法 .
您需要创建一个自定义适配器来组合您要滚动的所有内容,并将ListView的适配器设置为该适配器 .
我没有方便的示例代码,但如果你想要类似的东西 .
然后,您需要创建一个表示所有内容的适配器 . ListView / Adapters足够智能,可以处理不同类型,但您需要自己编写适配器 .
Android UI API并不像其他所有其他平台那样成熟,因此它没有与其他平台相同的细节 . 此外,当你在Android上做一些事情时,你需要处于一个android(unix)思维模式,在那里你期望做任何你可能需要组装较小部分功能的东西,并编写一堆你自己的代码来实现它工作 .
当我们在
ScrollView
里面放置ListView
时会出现两个问题 . 一个是ScrollView
测量其处于非正式模式的子项,因此ListView
设置自己的高度以仅容纳一个项目(我不知道为什么),另一个是ScrollView
拦截触摸事件因此ListView
不滚动 .但我们可以在
ScrollView
中放置ListView
并进行一些解决方法 . This post,由我解释了解决方法 . 通过这种解决方法,我们也可以保留ListView
的回收功能 .而不是把列表视图在Scrollview内部,将listview和Scrollview的开头之间的其余内容作为单独的视图放置,并将该视图设置为listview的 Headers . 因此,您最终只会获得负责Scroll的列表视图 .
这是我的代码版本,用于计算列表视图的总高度 . 这个对我有用: