如何将 GridView 放入 ScrollView
Posted
技术标签:
【中文标题】如何将 GridView 放入 ScrollView【英文标题】:How to put GridView inside ScrollView 【发布时间】:2012-10-03 06:43:03 【问题描述】:我必须设计布局,使整个布局应该滚动和内部布局我必须以Grid
形式显示相关内容,所以我决定使用GridView
。但问题是我无法使用GridView
在ScrollView
里面我也读过文档(文档还说我们不应该在ScrollView
里面使用GridView
)。但是我必须这样做,所以请给我一些想法。谢谢
【问题讨论】:
不要。你不能。 (好吧,你可以,但它很痛苦(不太适合),所以尽量避免它)。 谢谢@njzk2 但我必须设计这样的布局,所以你能告诉我一些其他应该看起来像这样的方式。 @Dipu:你在ScrollView
中只提到了GridView
。在对第一个答案的评论中,您提到在ScrollView
中添加更多Views
。考虑改写您的问题以包含尽可能多的细节。
其实可以,而且有一些很好的应用。我会更新答案。
@SiddharthLele 我的意思是我必须将 ImageView、TextView、Button 和 GridView 放入 listview 中。在按钮必须放入 GridView 这就是为什么必须使用滚动视图
【参考方案1】:
除了固有的滚动之外,GridView 肯定有其他好处。例如,单元格的一致动态布局将根据您传入的数据进行扩展和收缩。因此,当人们说想要这样的功能不好时,我认为这是错误的,因为您可能希望在滚动视图中使用动态图像(视图)网格,但希望整个滚动视图包含除网格之外的其他内容细胞。
现在,您可以这样做。检查答案here。它是一个可扩展高度的 GridView,您需要在项目中导入/创建它。这基本上意味着随着更多项目添加到 GridView,它只会扩展其高度,而不是保持其高度设置并使用滚动。这正是你想要的。
在您的项目中拥有 ExpandableHeightGridView 后,转到您希望 GridView 所在的 XML 布局。然后你可以做这样的事情(释义):
<ScrollView ...>
<RelativeLayout ...>
<com.example.ExpandableHeightGridView ... />
<other view items />
</RelativeLayout>
</ScrollView>
然后,在您设置 GridView 适配器的活动中,您要确保将其设置为展开。所以:
ExpandableHeightGridView gridView = (ExpandableHeightGridView) findViewById(R.id.myId);
gridView.setAdapter(yourAdapter);
gridView.setExpanded(true);
您想要这个可扩展的 GridView 的原因是,标准 GridView 不扩展是导致它滚动的原因。它固定在某个高度,然后随着更多项目填充它超出其视图边界,它变得可滚动。现在,有了这个,您的 GridView 将始终扩展其高度以适应其中的内容,因此永远不允许它进入其滚动模式。这使您可以在 ScrollView 中使用它,并在 ScrollView 中使用它上方或下方的其他视图元素,并让它们全部滚动。
这应该会为您提供您正在寻找的结果。如果您有任何问题,请告诉我。
【讨论】:
一件事,当我启动具有不同视图的应用程序时,布局会自动在底部滚动如何适应它请建议我 你能澄清一下吗?我不确定您所说的“以不同的视图启动应用程序”是什么意思。我还没有遇到过这个问题。 这种方法的问题是您失去了网格视图为您提供的性能优化,即。网格项目的回收。 您在此答案中的建议违背了GridView
的观点。您的应用程序可能会耗尽内存,并且性能会受到很大影响。解决方案是使用页眉或页脚视图,就像普通的ListView
一样。原生 GridView
可能不支持页眉或页脚视图,但有 custom implementations like this one 支持。使用其中之一,您可以获得相同的效果,而不会丢失视图回收。像你提出的黑客可能会解决问题,但它们只会在以后引起更严重的问题。
想要讲述在实现时发生的一种行为是扩展的 gridview 将滚动视图带到了底部,所以只想指出这样做://将 ScrollLayout 移回顶部,因为扩展 gridview 会将滚动视图移动到底部 ScrollView mainScrollView = (ScrollView) rootView.findViewById (R.id.scrollView); mainScrollView.smoothScrollTo(0,0);将一切就绪。希望它可以帮助别人!【参考方案2】:
我知道我迟到了,但我有另一个解决方案,我必须分享它并且完美运行。此处,该方法根据其包含的项目数计算 GridView 高度,并在运行时将高度设置为 GridView。
public void setGridViewHeightBasedOnChildren(GridView gridView, int columns)
ListAdapter listAdapter = gridView.getAdapter();
if (listAdapter == null)
// pre-condition
return;
int totalHeight = 0;
int items = listAdapter.getCount();
int rows = 0;
View listItem = listAdapter.getView(0, null, gridView);
listItem.measure(0, 0);
totalHeight = listItem.getMeasuredHeight();
float x = 1;
if( items > columns )
x = items/columns;
rows = (int) (x + 1);
totalHeight *= rows;
ViewGroup.LayoutParams params = gridView.getLayoutParams();
params.height = totalHeight;
gridView.setLayoutParams(params);
在您在 gridview 上调用 setAdapter
后,只需调用
setGridViewHeightBasedOnChildren( <yourGridView> , <no of grid view columns> )
它会起作用的。
你可以像往常一样在你的xml中定义gridview
让代码来处理它。 :)
【讨论】:
在调用 setGridViewHeightBasedOnChildren 方法之前,您是否在 gridview 上调用了 setAdapter?如果 gridview 有项目,那么它应该可以工作。 @vickey 如果项目数完全填满行数,你计算的高度有1个额外的行 如果您的 GridView 有垂直间距,则必须将其添加到 totalHeight。 这段代码有一个错误。将 if 块替换为: if( items > columns ) x = ((double) items ) /columns;行 =(int) Math.ceil(x);总高度 *= 行; 并声明 x 为 double 而不是 float。 如果您不想在此代码中使用自定义网格视图,它的工作原理【参考方案3】:我找到了一种方法,让 GridView在 ScrollView 内具有固定大小,并启用滚动。这使您无需滚动 GridView 的所有元素即可查看整个 ScrollView,而且对我来说,使用 ExpandableHeightGridView 更有意义。
为此,您必须实现一个扩展 GridView 的新类并重写 onTouchEvent() 以调用 requestDisallowInterceptTouchEvent(true)。 这样,父视图就会离开 Grid 拦截触摸事件。
GridViewScrollable.java:
package com.example;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.GridView;
public class GridViewScrollable extends GridView
public GridViewAdjuntos(Context context)
super(context);
public GridViewAdjuntos(Context context, AttributeSet attrs)
super(context, attrs);
public GridViewAdjuntos(Context context, AttributeSet attrs, int defStyle)
super(context, attrs, defStyle);
@Override
public boolean onTouchEvent(MotionEvent ev)
// Called when a child does not want this parent and its ancestors to intercept touch events.
requestDisallowInterceptTouchEvent(true);
return super.onTouchEvent(ev);
在 ScrollView 内将其添加到您想要的特征和边距的布局中:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:isScrollContainer="true" >
<com.example.GridViewScrollable
android:id="@+id/myGVS"
android:layout_
android:layout_
android:gravity="center"
android:numColumns="auto_fit"
android:stretchMode="columnWidth" />
</ScrollView>
然后在你的活动中得到它:
GridViewScrollable myGridView = (GridViewScrollable) findViewById(R.id.myGVS);
希望对你有帮助=)
在 Kotlin 中:
class GridViewScrollable @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : GridView(context, attrs, defStyleAttr)
override fun onTouchEvent(ev: MotionEvent?): Boolean
// Called when a child does not want this parent and its ancestors to intercept touch events.
requestDisallowInterceptTouchEvent(true)
return super.onTouchEvent(ev)
有一个烦人的警告:“自定义视图 GridViewScrollable 会覆盖 onTouchEvent 但不会覆盖 performClick”。请自行解决。
【讨论】:
已经很晚了但是这个gridview可以滚动? 它对我有用,但问题是投掷不起作用。 @ievgen 你把 android:isScrollContainer="true" 放在你的 ScrollView 里了吗? 这是让 GridView 与可变大小的单选按钮列表一起工作的唯一方法。我真的不想有滚动条,但 GridView 似乎会感到困惑,如果它太大,它会截断最后一行。 什么是GridViewAdjuntos
?【参考方案4】:
要在scrollview中使用gridview,设置scrollview android:fillViewport="true"
我知道在这里回答很晚,但可能对一些新开发人员有用。
【讨论】:
【参考方案5】:如果您使用了 dennisdrew 的答案,并且您的网格上方有内容,并且当您打开视图时它会被隐藏,只需在下面添加最后一行
ExpandableHeightGridView gridView = (ExpandableHeightGridView) findViewById(R.id.myId);
gridView.setAdapter(yourAdapter);
gridView.setExpanded(true);
gridView.setFocusable(false);
【讨论】:
【参考方案6】:最好在scrollview
中使用ExpandableHeightlistView
或ExpandableHeightGridView
。
逻辑
通过提供非常大的高度提示来计算整个高度。但不要使用该整数的最高 2 位;这些是为 MeasureSpec 模式保留的。
int expandSpec = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
欲了解更多信息,请使用演示探索以下示例
http://www.londatiga.net/it/programming/android/make-android-listview-gridview-expandable-inside-scrollview/
【讨论】:
您能否描述一些背景信息,说明为什么一个比另一个更好?【参考方案7】:我不会强迫这个问题。 GridView 在滚动视图中无法正常工作。而是将您的 gridview 转换为 recyclerview 并使用 gridLayoutManager 来解决问题。
【讨论】:
【参考方案8】:我还试图让 GridView
在 NestedScrollView
内滚动。
另一个问题的答案对我有帮助:https://***.com/a/38612612
启用您的 GridView 属性为
android:nestedScrollingEnabled="true"
原创海报:Droid_Dev
【讨论】:
非常有用的tanxxx【参考方案9】: gridView.setOnTouchListener(new View.OnTouchListener()
@Override
public boolean onTouch(View v, MotionEvent event)
v.getParent().requestDisallowInterceptTouchEvent(true);
return false;
);
// 设置 Touch Listener 用于处理 ScrollView 内的触摸
【讨论】:
以下是How do I write a good answer? 的一些指南。提供的这个答案可能是正确的,但它可以从解释中受益。仅代码答案不被视为“好”答案。来自review。【参考方案10】:如果你想在ScrollView
/RecyclerView
里面有GridView
,有2种情况:
如果您想让GridView
显示所有行,请参阅https://***.com/a/63724794/2914140。
如果您想在GridView
中显示一行,但可以滚动它(以显示其他行),请参阅https://***.com/a/26852498/2914140。
【讨论】:
【参考方案11】:相信这个解决方案对我有用!
android:nestedScrollingEnabled="true"
上面的网格视图内的代码可以滚动网格视图 并设置宽度和高度 android:layout_ android:layout_
即使在滚动视图中也可以使用 感谢之前的答案,我在之前的答案中发现了这一点。 感谢他们
【讨论】:
以上是关于如何将 GridView 放入 ScrollView的主要内容,如果未能解决你的问题,请参考以下文章