尝试理解ScrollView内LinearLayout中的边距

24
我需要在 ScrollView 中放置一个带边距的 LinearLayout。一开始,我所能想到的解决方法是在一个包含边距的 LinearLayout 中再放置一个 LinearLayout。如果将边距设置在外部的 LinearLayout 上,则无法起作用。

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:fillViewport="true"
    android:background="@color/layout_color_green">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="@color/layout_color_yellow">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="10dp"
            android:orientation="vertical"
            android:background="@color/layout_color_blue">
        </LinearLayout>
    </LinearLayout>
</ScrollView>

在此输入图片描述

我的问题是:为什么我需要这样做?

如果我只有一个LinearLayout,就不会有间距了...

例子:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:fillViewport="true"
    android:background="@color/layout_color_green">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        android:orientation="vertical"
        android:background="@color/layout_color_blue">
    </LinearLayout>
</ScrollView>

在此输入图片描述

在寻找类似问题时,我发现一些布局采用在ScrollView中使用内边距(padding)而不是在LinearLayout中使用外边距(margin)的方式,这也解决了我的问题,并且我不需要再嵌套一个LinearLayout。这是一种更优雅的解决方案。

然而,我仍然想知道为什么LinearLayout中的简单外边距在ScrollView中不起作用,因为如果它不在ScrollView中,则能够正常工作。

有人知道原因吗?

2个回答

16

我深入研究了源代码:

ScrollView 继承自 FrameLayout。这个控件本身有一些边距问题,而且 ScrollView 根本没有试图解决它们。测量时基本上会忽略边距。

但最终并不重要,因为你应该能够在 ScrollView 上定义内边距(这是一个断言,我没试过)。对于单个子视图,不需要使用边距。


1
但问题不仅仅在于边距。如果我将LinearLayout的高度设置为wrap_content,并且所有子元素的高度都设置为match_parent,则子元素实际上将是fill_parent,这是来自ScrollView的值,而不是直接父元素LinearLayout的值wrap_content。如果我在另一个LinearLayout中使用一个LinearLayout,则不会出现此问题。所以我猜测ScrollView还有更多我们不知道的东西! - rfgamaral
那么,您建议我使用填充而不是边距,并将“LinearLayout”的所有子项设置为“wrap_content”吗? - rfgamaral
我不能推荐填充,因为这是唯一的选择;android:fillViewport="false"不会强制LinearLayout成为fill_parent,就是这样。所以它不应该被拉伸,子元素也不应该被拉伸。 - Knickedi
这确实是在ScrollView内添加边距的唯一方法,这真的很恼人,你必须像这样进行黑客攻击。 - Warpzit
唯一的问题是,向ScrollView添加填充会使滚动条从屏幕边缘突出,并且看起来很丑,因为内容似乎会滚动到顶部和底部之外。很难通过文字解释清楚。请自行尝试以查看效果。 - aaronsnoswell
显示剩余3条评论

12

您好,Knickedi和Ricardo Amaral,

虽然这个答案已经被标记为已解决,但我想在这个问题上提供一些见解。

正如Knickedi所说,ScrollView扩展了FrameLayout。

因此,我的答案是,您可以设置ScrollView中LinearLayout的layout_gravity,然后layout_margin将像在FrameLayout中的LinearLayout一样在LinearLayout中起作用。

我曾遇到相同的问题,并采用了这种方法,它对我很有效。 :)

例如:

<ScrollView
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">

                <LinearLayout
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="top"
                    android:layout_marginTop="30dp"
                    android:orientation="vertical" >
</ScrollView>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接