ScrollView 内的图像网格 [英] Grid of images inside ScrollView

查看:23
本文介绍了ScrollView 内的图像网格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个包含文本和图像的屏幕.我希望图像像网格一样布局,如下所示,但我希望它们除了周围的 ScrollView 提供的滚动功能之外没有滚动功能.

I'm trying to create a screen with both text and images. I want the images to be laid out like a grid, as shown below, but I want them to have no scroll functionality other that the one provided by the surrounding ScrollView.

一张图片最能说明我的问题:

An image will best illustrate my question:

<ScrollView>
    <LinearLayout>
        <ImageView />
        <TextView />
        <GridView />
        <TextView />
    </LinearLayout>
</ScrollView>

在网格没有滚动功能的情况下,显示不同数量图像的网格的最佳方法是什么?

What is the best way to make show a grid of a varying number of images, where the grid does not have scroll functionality?

请注意,禁用 GridView 的滚动功能不起作用,因为这只会禁用滚动条,但不会显示所有项目.

Please note that disabling the scroll functionality for the GridView does not work, as this just disables the scrollbars but does not show all items.

更新:下图显示了在 GridView 中禁用滚动条后的样子.

Update: The image below shows what it looks like with scrollbars disabled in the GridView.

推荐答案

哦,男孩,是的,你会遇到这个问题的.让我抓狂的是 ListViews 和 GridViews 不能扩展来包裹他们的孩子,因为我们都知道他们除了滚动和回收他们的孩子之外还有更多有益的功能.

Oh boy, yeah, you're gonna have trouble with this one. It drives me nuts that ListViews and GridViews can't be expanded to wrap their children, because we all know that they have more beneficial features in addition to their scrolling and the recycling of their children.

不过,您可以轻松解决这个问题或创建自己的布局以满足您的需求.在我的脑海中,我能想到两种可能性:

Nonetheless, you can hack around this or create your own layout to suit your needs without too much difficulty. Off the top of my head, I can think of two possibilities:

在我自己的应用程序中,我在 ScrollView 中嵌入了 ListView.我通过明确告诉 ListView 与其内容一样高来做到这一点.我通过更改 ListView.onMeasure() 方法中的布局参数来做到这一点,如下所示:

In my own app I have embedded a ListView within a ScrollView. I have done this by explicitly telling the ListView to be exactly as high as its contents. I do it by changing the layout parameters right inside the ListView.onMeasure() method like so:

public class ExpandableListView extends ListView {

    boolean expanded = false;

    public ExpandableListView(Context context, AttributeSet attrs, int defaultStyle) {
        super(context, attrs, defaultStyle);
    }

    public boolean isExpanded() {
        return expanded;
    }

    public void setExpanded(boolean expanded) {
        this.expanded = expanded;
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // HACK!  TAKE THAT ANDROID!
        if (isExpanded()) {         
            // Calculate entire height by providing a very large height hint.
            // View.MEASURED_SIZE_MASK represents the largest height possible.
            int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
                        MeasureSpec.AT_MOST);
            super.onMeasure(widthMeasureSpec, expandSpec);

            LayoutParams params = getLayoutParams();
            params.height = getMeasuredHeight();
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}

这是可行的,因为当您为 ListView 提供 AT_MOST 模式时,它会在 onMeasure 方法内为您创建并测量其所有子项(我发现了这一点通过浏览源代码).希望 GridView 的行为相同,但如果不是,您仍然可以自己测量 GridView 的所有内容.但是如果你能欺骗 GridView 为你做这件事会更容易.

This works because when you give the ListView a mode of AT_MOST, it creates and measures all of its children for you, right inside the onMeasure method (I discovered this by browsing through the source code). Hopefully GridView behaves the same, but if it doesn't, you can still measure all the contents of the GridView yourself. But it would be easier if you could trick the GridView into doing it for you.

现在,您必须记住,此解决方案将完全禁用使 GridView 如此高效的视图回收,并且所有这些 ImageView 将在内存中,即使它们不可见.我的下一个解决方案也是如此.

Now, you must keep in mind that this solution would completely disable the view recycling that makes GridView so efficient, and all those ImageViews will be in memory even if they're not visible. Same goes with my next solution.

另一种可能性是放弃 GridView 并创建自己的布局.您可以扩展 AbsoluteLayoutRelativeLayout.例如,如果你扩展 RelativeLayout,你可以将每张图片 LEFT_OF 放在前一张,跟踪每张图片的宽度,直到你用完那一行的空间,然后通过将新行的第一个图像 BELOW 放在最后一行的最高图像开始下一行.要使图像水平居中或在等间距的列中,您将不得不经历更多的痛苦.也许 AbsoluteLayout 更好.不管怎样,有点痛苦.

The other possibility is to ditch the GridView and create your own layout. You could extend either AbsoluteLayout or RelativeLayout. For example, if you extend RelativeLayout, you could place each image LEFT_OF the previous one, keeping track of the width of each image until you run out of room on that row, and then start the next row by placing the first image of the new row BELOW the tallest image of the last row. To get the images horizontally centered or in equally-spaced columns you'll have to go through even more pain. Maybe AbsoluteLayout is better. Either way, kind of a pain.

祝你好运.

这篇关于ScrollView 内的图像网格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆