ScrollView中的图像网格

han*_*ide 63 user-interface android gridview scrollview imageview

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

图像最能说明我的问题:

替代文字

<ScrollView>
    <LinearLayout>
        <ImageView />
        <TextView />
        <GridView />
        <TextView />
    </LinearLayout>
</ScrollView>
Run Code Online (Sandbox Code Playgroud)

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

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

更新:下图显示了在GridView中禁用滚动条的情况.

替代文字

Nei*_*aft 186

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

尽管如此,你可以解决这个问题或创建自己的布局,以满足您的需求而不会有太大的困难.在我的头顶,我可以想到两种可能性:

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

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

祝好运.

  • 我可能还会提到,如果你想给GridView一个固定的大小,并启用在ScrollView中滚动,那么在Android上就可以了.但是你必须覆盖`GridView.onTouchEvent()`来调用`requestDisallowInterceptTouchEvent(true)`(参见那个神奇的小方法的文档).但是如果你这样做,你可能会看到在2.2及更高版本上滚动的不一致,因为Romain Guy _really_不希望你有嵌套滚动.;-) (3认同)
  • 好的解决方案 但是,我不认为你真的想在这里使用名称"ExpandableListView",因为它也是一个内部的android组件.尽管在Java中避免命名空间冲突非常容易,但它仍然有点令人困惑. (2认同)