如何将 GridView 放入 ScrollView

Posted

技术标签:

【中文标题】如何将 GridView 放入 ScrollView【英文标题】:How to put GridView inside ScrollView 【发布时间】:2012-10-03 06:43:03 【问题描述】:

我必须设计布局,使整个布局应该滚动和内部布局我必须以Grid 形式显示相关内容,所以我决定使用GridView。但问题是我无法使用GridViewScrollView 里面我也读过文档(文档还说我们不应该在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 中使用ExpandableHeightlistViewExpandableHeightGridView

逻辑

通过提供非常大的高度提示来计算整个高度。但不要使用该整数的最高 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】:

我还试图让 GridViewNestedScrollView 内滚动。

另一个问题的答案对我有帮助: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的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 GridView 或 TableView 在颤振中制作填字游戏

EF 更新未更新 GridView

如何让 Gridview 呈现 THEAD?

将 gridview 行数据添加到文本框和标签中

没有数据绑定时使 GridView 页脚可见

.net高手:我想在gridview加入一列图片