Android RelativeLayout:如何在包含在ScrollView中时对齐至底部?

32
我遇到的问题似乎是这样的:如果我在RelativeLayout中有一个视图(例如myButton),设置为alignParentBottom - 如下所示的代码 - 然后用scrollview包装RelativeLayout(必要,以便在较小的屏幕或方向更改为横向时可以查看内容),则当父底部不可见时(例如更改为横向方向),myButton将显示在页面顶部,而不是底部。

如何对齐视图到屏幕底部并使其保留在底部,即使底部低于滚动条?

<ScrollView
android:id="@+id/mainScrollView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:fillViewport="true">



<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/topLayout"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">



... lots of views and stuff


<Button android:layout_alignParentBottom="true" 
android:id="@+id/myButton"  
android:text="Click Me" />

</RelativeLayout>
</ScrollView>   

你知道今天怎么做吗? - the beest
5个回答

28

将按钮从滚动视图中移除,在线性布局中包装滚动视图和按钮,将滚动视图的高度设置为0dip,并将其权重设置为1,不要为按钮设置任何权重属性,这样滚动视图可以占据所有剩余的空间,只保留按钮的空间在底部。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ScrollView 
        android:layout_width="match_parent"
        android:layout_height="0dip"
        android:layout_weight="1">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

        ....lots of views...


        </LinearLayout>
    </ScrollView>

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:text="Button" />

</LinearLayout>

8
但这样会使“按钮”始终保持在屏幕底部,即使“滚动视图”是可滚动的,对吗? - timemanx
这是我喜欢的解决方案,但要注意“重量”对性能不利。 - superuser
很好的回答,现在解释一下为什么layout_height0layout_weight1可以有效地产生所需的效果。 - aroth

7
使用fill_parent作为ScrollView子项的高度是没有意义的。您告诉RelativeLayout始终与其父级一样高。在这种情况下,ScrollView变得无用! RelativeLayout的高度应设置为wrap_content,在这种情况下,根据RelativeLayout包含的内容,alignParentBottom可能不起作用。您应该简单地使用LinearLayout,这将更加简单明了。

我不明白为什么你说ScrollView变得没用了,它的作用是允许滚动,并且它做到了…所以我必须使用它。我必须使用RelativeLayout以便可以使用android_alignParentBottom。我不明白使用LinearLayout如何解决这个问题,因为那样我就不能将myButton对齐到屏幕底部。难道不可能同时将视图对齐到屏幕底部并支持滚动吗? - JohnRock
如果子元素的高度为fill_parent,那么它是无用的。fill_parent的意思是“我想和我的父元素一样高”。因此,如果ScrollView的内容和ScrollView本身一样大,它就不会滚动。 - Romain Guy
好的。我感谢您的指导。然而,布局确实可以滚动,这不是我要解决的问题。 - JohnRock
我正在解释为什么您的布局不能像您期望的那样工作,因为它无法使用fill_parent。 - Romain Guy
嗨,Romain,我处于类似的情况(除了我某些不可编辑的代码有点绑定到RelativeLayout上)。 RelativeLayout 设置为wrap_content,我的按钮布局设置为alignParentBottom,但正如OP所说,按钮出现在相对布局的顶部。是否存在一些尝试确保相对布局的所有元素始终可见的内容? - Sam
我经常遇到的一个场景是,当软键盘打开时(例如登录屏幕),我希望视图可以滚动,以便用户可以在不关闭键盘的情况下滚动到登录按钮。有没有更常用的方法来实现这个功能? - Stephen Kidson

4

好的,你可以尝试这个。

<LinearLayout android:id="@+id/parentLayout"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <ScrollView android:id="@+id/mainScrollView"
        android:layout_width="fill_parent" android:layout_height="fill_parent"
        android:layout_weight="1" xmlns:android="http://schemas.android.com/apk/res/android"
        android:fillViewport="true">



        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/topLayout" android:layout_width="fill_parent"
            android:layout_height="fill_parent">



            ... lots of views and stuff


            <Button android:layout_alignParentBottom="true" android:id="@+id/myButton"
                android:text="Click Me" />

        </RelativeLayout>
    </ScrollView>
</LinearLayout>

谢谢伙计!我遇到了同样的问题,开始觉得这是不可能的。你的解决方案帮了我很多。 - Androider

3

对我来说,这些解决方案都不够令人满意,因此我会发布自己的解决方案。

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <!-- lots of stuff -->

        <Space
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>

</ScrollView>

简单解释:当有很多空间(例如纵向)时,空间视图将填充该空间并将按钮向下推。当没有空间(例如横向)时,空间视图将具有0高度,并且按钮直接位于内容下方。


1
是的,将此行添加到RelativeLayout将有所帮助。android:fillViewport="true" - Sreekant Shenoy
刚刚偶然发现这个,使用<Space>有什么优势吗? 你可以直接将gravity=bottom、height=0dp和weight=1添加到按钮中,如果效果相同,不是吗? - Leviathan

-1

有点晚了,但最简单的解决方案是添加

android:below="@id/lots_of_stuffs"

像这样:

<ScrollView 
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/mainScrollView"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:fillViewport="true">

   <RelativeLayout
     android:id="@+id/topLayout"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent">


     <LinearLayout
       android:id="@+id/lots_of_stuffs" >

       ... lots of views and stuff

     </LinearLayout>

    <Button android:layout_alignParentBottom="true" 
      android:id="@+id/myButton"  
      android:text="Click Me"
      android:below="@id/lots_of_stuffs" /> <!-- Here is the "hack" -->

   </RelativeLayout>
</ScrollView>  

有点晚了,而且还不是一个合适的解决方案,这会将按钮拉伸到其填充高度。 - Shivansh

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