在ScrollView中向布局底部添加视图

79
我的布局基本上看起来像这样:
<ScrollView>
    <RelativeLayout>
        <BunchOfViews/>
        <ImageView android:layout_alignParentBottom="true"/>
    </RelativeLayout>
</ScrollView>

我有一个ScrollView,所以无论屏幕的高度如何,整个布局始终可见。问题是,在非常高的屏幕上,我仍然希望我的ImageView在底部。但是,ScrollView的子项似乎没有定义底部。该View位于布局顶部。有什么简洁的方法可以解决这个问题?

11个回答

170
我遇到了同样的问题。我从未找到一个非常令人满意的解决方案,但这是我的做法。也许有人有更好的方法,我不喜欢添加没有任何作用的布局。
我的hack方法是在scrollview底部添加一个虚拟的linearlayout,它具有fill_parent以占用所有空间并强制scrollview填充整个屏幕。然后将任何组件添加到该linearlayout中。
这是我的某个采用这种方法的布局:
<ScrollView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:fillViewport="true" >

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_marginTop="15px" >

        <!-- bunch of components here -->

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_below="@+id/spinner"
            android:layout_marginTop="5px"
            android:gravity="center_horizontal|bottom"
            android:paddingTop="2px" >

            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingLeft="20px"
                android:paddingRight="20px"
                android:text="Delete" />
        </LinearLayout>
    </RelativeLayout>
</ScrollView>

67
android:fillViewport是关键部分,很容易被忽略。 - daniel.gindi
2
“android:layout_below="@+id/spinner"” 部分可能不应该在 'id' 前面指定 '+'... 可能这不是第一次定义该 id 的地方(它将在“这里有一堆组件”部分的某个地方定义,并且那里会有 +id)。 - jimmyorr
非常有帮助,谢谢 :) 我们也可以称之为dimen.xml文件,但这取决于客户的要求。 - sharma_kunal
这对我有用,但我必须将背景设置为内部LinearLayout透明,才能看到其后面的视图。 - android:background="@android:color/transparent" - karthik prasad
1
fill_parent已被弃用。这个相同问题的答案更加更新:https://dev59.com/zXE95IYBdhLWcg3wMa91#41120823 - Tom Bevelander
显示剩余2条评论

83

我曾经遇到了同样的问题,后来找到了这个页面:

http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/

基本上,你需要将ScrollView的android:fillViewport设置为true,这将允许子视图扩展到与ScrollView本身相同的高度,填满空间。然后,只需要将一个子控件的layout_height设置为fill_parent,将layout_weight设置为1,即可将该控件“弹出”以填充空白处。

请注意,如果ScrollView的内容已经足够高以填满ScrollView,则android:fillViewport没有效果,因此该设置仅在需要时生效。

我的最终XML看起来类似于这样:

<ScrollView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:fillViewport="true">
    <LinearLayout
        android:orientation="vertical"
        android:layout_height="wrap_content">
        <LinearLayout
            android:layout_height="fill_parent"
            android:layout_weight="1">
            <!-- this expands to fill the empty space if needed -->
        </LinearLayout>

        <!-- this sits at the bottom of the ScrollView,
        getting pushed out of view if the ScrollView's
        content is tall enough -->
        <ImageView
            android:layout_height="wrap_content"
            android:src="@drawable/footer_image">
        </ImageView>
    </LinearLayout>
</ScrollView>

1
这很好,但是我的屏幕填充项是一个EditText,并且在输入的行数很多时被允许向屏幕底部延伸。有没有办法防止这种情况发生,以便滚动视图只在显示软键盘时才启动? - finiteloop
1
这很棒。简单而整洁。 - Maggie
这应该是被接受的答案,因为ScrollView的子高度应该是“wrap_content”。 - Aleks Nine
非常感谢,这对我来说效果很好,它还适用于嵌套的ScrollView。 我认为有两件事需要记住- 1- 在ScrollView或NestedScrollView中添加android:fillViewport="true"。 2- 将android:layout_weight="1"设置为内部LinearLayout。 这里是Romain Guy提供的相同解决方案的链接 [链接](http://www.curious-creature.com/2010/08/15/scrollviews-handy-trick/) - shivam
按照Android Studio的建议,使用android:layout_height="0dp"来设置可展开布局的高度。 - andreaciri

21

看起来LinearLayout并不是必须的,重要的是fillViewPort属性。你可以直接使用:

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottomParent="true">

现在您已经指定了RelativeLayout至少与屏幕大小相同。


8
这个实际上是有效的。答案不够清晰 - 在你的ScrollView中添加fillViewPort="true"即可。 - Dmitry Zaytsev

16

它对我完美地发挥作用 android:fillViewport="true"


我已经将这个属性添加到了ScrollView,它的效果非常好! - makerj
将此添加到“ScrollView”中,最终使其对我起作用。 - VarunBarad

10

Joel Malone的回答在ScrollView内向底部添加View可以解决这个问题。我的解决方案几乎相同,仅是使用了Space小部件来填充父布局内剩余的高度。像这样:

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    >
    <LinearLayout
        android:orientation="vertical"
        android:layout_height="wrap_content"
        >
        <android.support.v4.widget.Space
            android:layout_height="match_parent"
            android:layout_weight="1"
            />
    <ImageView
        android:layout_height="wrap_content"
        android:src="@drawable/footer_image"
        />
    </LinearLayout>
</ScrollView>

注意:

  • fill_parent在其他答案中已经被标记为废弃的很久了;
  • 相比于一个空的LinearLayout去填充父布局的剩余部分,我认为Space更加合适(这是它的设计目的);
  • 最后,请不要忘记在ScrollView的开头添加这个重要属性:android:fillViewport="true"。它们一起实现这个技巧。

注意:

  • fill_parent已经被其他答案标记为废弃的很久了;
  • 与使用空的LinearLayout来填充父布局的剩余部分相比,我认为Space更加适合(因为它就是为此而设计的);
  • 最后,在ScrollView开始处不要忘记添加这个重要的属性:android:fillViewport="true"。它们两者一起实现这个技巧。

1
虽然最高评分的方法可行,但这是我最喜欢的解决方案。使用空格是一个不错的技巧,它不需要额外的嵌套布局,但仍然可以与多个“底部附加”元素一起使用。 - Peter F
一点说明:由于设置了layout_weight =“1”,因此Space的高度应设置为“0dp”。将高度设置为“match_parent”将显示相同的结果,但会在Android Studio中显示警告。 - Peter F
1
@PeterF 没错;我个人喜欢将高度设置为match_parent(更易理解)。由于IDE这样说,应该推荐将其设置为0dp。 - Anthonyeef

4
只需将 android:fillViewport="true" 属性添加到您的 ScrollView 中,您就可以得到您需要的效果。

1
在您想要位于底部的视图上,使用 android:gravity="bottom"

0
ScrollView view = new ScrollView( this );
ScrollView.LayoutParams lps = new FrameLayout.LayoutParams( FILL_PARENT, FILL_PARENT, Gravity.CENTER );
LinearLayout layout = new LinearLayout( this );
// what ever you want in the Layout 
view.addView( layout, lps );

你应该始终优先在XML中设置布局的高度和宽度,避免在代码中进行设置。 - JaydeepW

0

以下是如何使用 ConstraintLayout 将图像视图对齐到底部的方法:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/content_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/text_view"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="Text 1"
            app:layout_constraintBottom_toTopOf="@+id/space_view"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="parent" />

        <Space
            android:id="@+id/space_view"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@+id/image_view"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/text_view" />

        <ImageView
            android:id="@+id/image_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="..."
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/space_view" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</ScrollView>

0

我尝试过很多次将滚动视图与屏幕底部对齐,但根据这个链接,这是不可能的。 https://newbedev.com/how-do-i-align-views-at-the-bottom-of-the-screen

我找到的方法是创建一个高度为1dp并带有ID(比如android:id="@+id/bottomView")的视图,放置在XML页面的底部

现在只需将这些属性添加到您的滚动视图中...

<ScrollView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"
        android:fillViewport="true"
        android:layout_alignBottom="@+id/bottomView"
        >

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