安卓RelativeLayout如何在两个视图下方排列?

56

我有一个像这样的 RelativeLayout

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/single_row"
    android:padding="12dip">

    <ImageView
        android:id="@+id/page_image"
        android:layout_marginRight="6dip"
        android:layout_width="66dip"
        android:layout_height="66dip"
        android:layout_alignParentLeft="true"
        android:src="@drawable/no_photo" />
    <TextView
        android:id="@+id/page_name"
        style="@style/pulse_content"
        android:layout_alignTop="@id/page_image"
        android:layout_toRightOf="@id/page_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/page_desc"
        android:layout_below="@id/page_name"
        style="@style/pulse_content"
        android:layout_alignLeft="@id/page_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Principal Consultant" />
    <Button
        android:id="@+id/follow_button"
        android:layout_below="@id/author_image"
        android:layout_marginTop="15dip"
        android:layout_alignParentBottom="true"
        android:text="Follow"
        style="@style/follow_button" />
</RelativeLayout>

我遇到的问题是我想要将follow_button放置在page_descpage_image下面。有时候page_desc的高度会大于图像的大小,有时则不会。问题是,如果我将follow_button放在图像或描述下方,那么另一个元素就会被裁剪。是否有一种有效的方法来确保图像或page_desc始终可见且在按钮上方?


你可以尝试将page_desc和page_image放入LinearLayout中,然后将follow_button放在LinearLayout下方。 - Sephy
我本来希望避免这种情况,因为它会创建额外的对象(从而占用内存),但如果没有其他选择,我想我必须这样做。 - Ben
你可以强制两个文本视图都具有特定的高度。但是我会使用@Sephy的答案。如果这是某种ListView的一部分,它应该在你的Adapter的getView()方法中被重用。 - bgs
在相对布局中使用LinearLayout不会增加额外的内存负担,相信我。可以查看一些开源布局文件,它们通常包含有嵌套的布局(或解压APK文件查看)。如果需要快速修复问题,可以采用这种解决方案,有空再回来处理该问题。 - Blundell
我认为避免使用线性布局是过早的优化。这样的布局在G1上完全可以正常工作。 - renam.antunes
3个回答

50

这是你需要的:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="@drawable/single_row"
    android:padding="12dip">

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/page_image"
            android:layout_marginRight="6dip"
            android:layout_width="66dip"
            android:layout_height="66dip"
            android:layout_alignParentLeft="true"
            android:src="@drawable/no_photo" />
        <TextView
            android:id="@+id/page_name"
            style="@style/pulse_content"
            android:layout_alignTop="@id/page_image"
            android:layout_toRightOf="@id/page_image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:id="@+id/page_desc"
            android:layout_below="@id/page_name"
            style="@style/pulse_content"
            android:layout_alignLeft="@id/page_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Principal Consultant" />
    </RelativeLayout>

    <Button
        android:id="@+id/follow_button"
        android:layout_marginTop="15dip"
        android:text="Follow"
        style="@style/follow_button" />
</LinearLayout>

11
使用RelativeLayout的重点是避免嵌套LinearLayout。 :( - SMBiggs
4
我无法只使用一个RelativeLayout解决这个问题。您无法定义一个元素在另外两个元素下方。如果您可以在不嵌套视图组的情况下解决此问题,请发布另一个答案。另外,哪里说避免嵌套是RelativeLayout的目的?它在许多情况下可能用于此目的,但也有例外情况。 - Zsombor Erdődy-Nagy
1
我本希望有一个更优雅的解决方案,但看起来你是对的。 - SMBiggs
显然,这并不让任何人感到惊讶 ;) - Choletski

8
这里需要进行的更改很少。你的布局大部分是正确的,然而有一个选项在捣乱。AlignParentXXXX 通常会优先于 LayoutXXXX 选项,所以当你将 Button 的 AlignParent 设置为 AlignParentBottom 时,就告诉 RelativeLayout 按钮的大小不是父布局大小计算的。
你可以通过从 Button 中简单地移除 AlignParent="true" 来解决此问题。下面是经过测试的结果代码。我认为这个解决方案符合你的期望。
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/single_row"
    android:padding="12dip">

    <ImageView
        android:id="@+id/page_image"
        android:layout_marginRight="6dip"
        android:layout_width="66dip"
        android:layout_height="66dip"
        android:layout_alignParentLeft="true"
        android:src="@drawable/no_photo" />
    <TextView
        android:id="@+id/page_name"
        style="@style/pulse_content"
        android:layout_alignTop="@id/page_image"
        android:layout_toRightOf="@id/page_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/page_desc"
        android:layout_below="@id/page_name"
        style="@style/pulse_content"
        android:layout_alignLeft="@id/page_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Principal Consultant" />
    <Button
        android:id="@+id/follow_button"
        android:layout_below="@id/author_image"
        android:layout_marginTop="15dip"
        android:text="Follow"
        style="@style/follow_button" />
</RelativeLayout>

当父级容器使用WrapContent时,我在AlignParent方面遇到了许多类似的问题。如果没有做好准备,上下定位会产生不良行为。我发现,通常最好只使用其中之一(如果需要),并将其余部分排列在其上方或下方。


抱歉各位,我本意是在另一个问题上提供悬赏。对于造成的混淆,我深表歉意。 - Ben

3

由于RelativeLayout中的所有内容都是相互依赖的,因此放置的顺序并不重要,但如果您尝试在创建一个视图之前访问它,则会产生影响。例如,使用android:layout_below属性并不完全适用于按钮。如果您将其他视图设置为android:layout_above按钮,则会使这些视图始终位于按钮上方。

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/single_row"
    android:padding="12dip">

    <Button
        android:id="@+id/follow_button"
        android:layout_marginTop="15dip"
        android:layout_alignParentBottom="true"
        android:text="Follow"
        style="@style/follow_button" />
    <ImageView
        android:id="@+id/page_image"
        android:layout_above="@id/follow_button"
        android:layout_marginRight="6dip"
        android:layout_width="66dip"
        android:layout_height="66dip"
        android:layout_alignParentLeft="true"
        android:src="@drawable/no_photo" />
    <TextView
        android:id="@+id/page_name"
        android:layout_above="@id/follow_button"
        style="@style/pulse_content"
        android:layout_alignTop="@id/page_image"
        android:layout_toRightOf="@id/page_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/page_desc"
        android:layout_above="@id/follow_button"
        android:layout_below="@id/page_name"
        style="@style/pulse_content"
        android:layout_alignLeft="@id/page_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Principal Consultant" />
</RelativeLayout>

将控件与父控件底部对齐并不是通用解决方案,但我更喜欢它而不是添加嵌套布局。 - Petr Gladkikh

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