ScrollView 中的 LinearLayout 不展开

390

我有一个ScrollView里面包含一个LinearLayoutLinearLayout设置了android:layout_height="fill_parent"属性,但是它没有充满整个ScrollView。我的布局类似于:

level    layout    layout_width    layout_height
1    LinearLayout    fill_parent    fill_parent
2    LinearLayout    fill_parent    wrap_content
3    (some irrelevant stuff)
2    ScrollView      fill_parent    fill_parent <-- this expands full height
3    LinearLayout    fill_parent    fill_parent <-- this does not (has orientation=vertical)
(following stuff probably are irrelevant, but just to be sure:)
4    TextView        fill_parent    fill_parent
4    LinearLayout    fill_parent    wrap_content
我发现在Android Layout Editor中,如果我选择ScrollView(在大纲面板中),它会用红色边框突出显示,填充到屏幕底部,但是当我选择LinearLayout时,其突出显示的高度不会扩展到屏幕底部。我该如何使其扩展到底部呢?
我想要实现的效果是,在文本下方有一个按钮(在第4个级别的LinearLayout中只有一个按钮)。文本可能很长,需要滚动条,这样用户就必须向下滚动才能看到按钮。如果文本不足以出现滚动条,则希望包含按钮的LinearLayout粘着屏幕底部。
起初我认为不应该发布完整的XML,因为通常在问题中看到大量的代码会让人失望。然而,似乎有必要,所以这是完整的布局。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:id="@+id/video_layout"
        android:focusable="true"
        style="@style/VideoLayout">
        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:foreground="@android:drawable/ic_media_play"
            android:foregroundGravity="center">
            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/video_thumb"
                android:padding="5dip"
                android:background="#454545"/>
        </FrameLayout>
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:focusable="true"
            style="@style/VideoTitle"
            android:id="@+id/video_title"
            android:layout_gravity="center"
            android:layout_weight="1"/>
    </LinearLayout>
    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1">
        <!-- this ScrollView expands the full height of the screen.
             However, the next LinearLayout does not expand the full height of the ScrollView -->
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:layout_gravity="fill"
            android:orientation="vertical"
            android:id="@+id/info_layout">
            <TextView
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:id="@+id/info_body"
                style="@style/InfoText"/>
            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                style="@android:style/ButtonBar">
                    <Button
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:layout_weight="1"
                        android:text="@string/button_readmore"
                        android:id="@+id/btn_read_more"/>
            </LinearLayout>
        </LinearLayout>
    </ScrollView>
</LinearLayout>

目前我已经在有问题的LinearLayout上使用了android:layout_gravity="bottom",这使得按钮无论如何都会停留在屏幕底部。但是这也使得文本粘在屏幕底部,这并不完全是我想要的。

更新: 取消之前的操作,android:layout_gravity="bottom"会使ScrollView无法滚动。还有其他的想法吗?

7个回答

1004

最终我自己找到了解决方案。问题不在于 LinearLayout,而是在于 ScrollView (看起来很奇怪,因为 ScrollView 在扩展,但是 LinearLayout 没有)。

解决方案是在 ScrollView 上使用 android:fillViewport="true"


8
请注意,LinearLayout会在垂直方向上扩展,但除非它包含使用android:weight消耗额外空间的控件,否则这可能不会在布局中得到反映。 - Paul Lammertsma
这真的很有帮助。谢谢你。但是有时候没有这段代码也能正常工作。你知道为什么吗? - Ashokchakravarthi Nagarajan
4
我感觉非常不舒服,坐了几个小时一直在搜索我的代码出了什么问题。这个参数是用来做什么的?你什么时候需要将它设为false? - MyWay
@Prasad 将你的线性布局高度设置为match_parent。 - williamj949
和 @MyWay 一样,我也有相同的经历。这些默认设置真是让人难以置信。 - Akito
显示剩余2条评论

24

我知道这篇文章很老了,对于那些不想使用android:fillViewport="true"的人,因为它有时无法将edittext提到键盘上方。解决方法是使用RelativeLayout而不是LinearLayout。


10

你能提供你的布局XML吗?这样做可以让其他人用最小的努力重新创建此问题。

你可能需要设置

android:layout_weight="1"
对于您想要展开的项目。

1
谢谢你的回答。我尝试了你的建议,但没有起作用。我还更新了我的问题,包括布局 XML。 - Felix

8
解决方案是在滚动视图上使用 android:fillViewport="true",并尽量使用 "wrap_content" 而不是 "fill_parent",因为 "fill_parent" 已经被弃用了。

2

我曾动态地使用以下方法。我有一个LinearLayout,其中使用ScrollView作为子元素。然后我再次使用LinearLayout并将任何您想要添加到此LinearLayout的视图添加到其中,然后将此LinearLayout添加到ScrollView中,最后将此ScrollView添加到LinearLayout中。然后您就可以在ScrollView中滚动,没有任何内容会被隐藏。

LinearLayout(父级) - ScrollView(LinerLayout的子元素) - LinearLayout(ScrollView的子元素) - 在此处添加textView、按钮、spinner等任何您想要的视图。然后将此LinearLayout添加到ScrollView中。因为ScrollView只适用于一个子元素,最后将此ScrollView添加到LinearLayout中。如果定义的区域超出屏幕大小,则会在ScrollView内获得滚动条。


但是这种解决方案会使XML变得更加复杂,并且需要更多的时间来膨胀。 - twlkyao

1
在我的情况下,我没有给出LinearLayout(ScrollView的子项)的方向。因此,默认情况下它采用水平方向,但是ScrollView垂直滚动,请检查是否将“android:orientation =“vertical””设置为您的ScrollView的子项(在LinearLayout的情况下)。这就是我的情况,希望能帮助到别人。

.


1
所有这里的答案对我来说都没有完全起作用。 为了总结一下我们想要做的事情: 我们有一个ScrollView,它应该填充设备的视口,因此在布局xml中将fillViewport设置为“true”。 然后,在ScrollView内部,我们有一个LinearLayout包含其他所有内容,该LinearLayout的高度应至少与其父ScrollView一样高,因此应该在LinearLayout底部(底部)的东西实际上就在屏幕底部(或者在LinearLayout的内容比屏幕更高时在ScrollView底部)。
示例activity_main.xml布局:
<ScrollView
    android:id="@+id/layout_scrollwrapper"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fillViewport="true"
    android:layout_alignParentTop="true"
    android:layout_above="@+id/layout_footer"
    >
<LinearLayout
    android:id="@+id/layout_scrollwrapper_inner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    >
...content which might or might not be higher than screen height...
</LinearLayout>
</ScrollView>

然后,在活动的onCreate中,我们“等待”LinearLayout的布局完成(暗示其父布局也已经完成),然后将其最小高度设置为ScrollView的高度。因此,即使ScrollView未占据整个屏幕高度,它也可以正常工作。 无论您在ScrollView还是内部LinearLayout上调用.post(...) ,差别不会太大,如果一个不起作用,请尝试另一个。

public class MainActivity extends AppCompatActivity {

@Override // Activity
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    LinearLayout linearLayoutWrapper = findViewById(R.id.layout_scrollwrapper_inner);

    ...

    linearLayoutWrapper.post(() -> {
        linearLayoutWrapper.setMinimumHeight(((ScrollView)linearLayoutWrapper.getParent()).getHeight());
    });
}
...
}

不幸的是,这不是一个仅限于xml的解决方案,但对我来说已经足够好了,希望它也能帮助其他在搜索此问题解决方案时受折磨的Android开发人员;D


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