RelativeLayout将占据全屏以适应wrap_content。

131

当没有任何元素的 layout_height="fill_parent",也就是说所有元素的高度都是 wrap_content 时,为什么 FOOBARZ 都会被放到底部布局呢? enter image description here

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/feed_u"
        android:layout_width="50dip"
        android:layout_height="50dip"
        android:layout_marginLeft="5dip"
        android:scaleType="centerCrop"
        android:drawableTop="@android:drawable/presence_online"
        android:text="U" />
    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/feed_u">
        <ImageView
            android:id="@+id/feed_h"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@android:drawable/btn_minus" />
        <ImageView
            android:id="@+id/feed_ha"
            android:layout_toLeftOf="@id/feed_h"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@android:drawable/btn_plus" />
        <TextView
            android:id="@+id/feed_t"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Title">
        </TextView>
        <TextView
            android:id="@+id/feed_a"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Band"
            android:layout_below="@id/feed_t">
        </TextView>
        <TextView
            android:id="@+id/feed_s"
            android:layout_below="@id/feed_a"
            android:text="S"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content">
        </TextView>
        <TextView
            android:id="@+id/feed_tm"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:text="FOOBARZ"
            android:layout_height="wrap_content"
            android:layout_width="wrap_content">
        </TextView>

    </RelativeLayout>
</RelativeLayout>

1
使用 hierarchyviewer 或者 Eclipse 中的层次结构视图来确定问题出在哪里:http://developer.android.com/guide/developing/debugging/debugging-ui.html - CommonsWare
在Eclipse中,层次结构视图透视图在哪里?在哪个屏幕上? - hunterp
1
窗口 > 打开透视图 > 其他... - 虽然我认为你已经得到了答案,感谢 @alextc。 - CommonsWare
@CommonsWare 我找到了它,但是它是空的,我该如何将布局加载到其中? - hunterp
8个回答

272

来自RelativeLayout的文档:

类概述

一种布局,其中子项的位置可以相互或相对于父项描述。

请注意,RelativeLayout的大小与其子项的位置之间不能存在循环依赖关系。 例如,您不能将高度设置为WRAP_CONTENT的RelativeLayout,并将其子项设置为ALIGN_PARENT_BOTTOM

类文档

这恰好是你的情况。RelativeLayout做不到这一点。


3
我删除了align_parentBottom属性,现在布局只占屏幕的1/10,我该如何将FOOBARZ放在底部? - hunterp
2
仅凭短暂的查看,我会建议:将FOOBARZ TextView移动到外部RelativeLayout,并设置android:layout_below="@id/feed_u"。但我不确定这是否符合您的要求。 - user658042
1
请注意,当使用大型可绘制对象作为背景时,也可能会发生这种情况。为了解决这个问题,将主要内容提取到子布局中,并将背景设置为兄弟节点的 <ImageView>,并将其放在主要内容后面。 - Ky -
1
我注意到孩子们也不被允许使用match_parentlayout_height - Daniel F
1
这解释了为什么它不起作用,但没有提供解决方案。 - Christopher Pickslay
显示剩余2条评论

57

对于像我一样寻找解决方法的人,可以使用FrameLayout替代RelativeLayout.

然后你可以像下面这样将预期对象的重力设置为右下方。

<TextView
    android:layout_gravity="bottom|right"
    android:text="FOOBARZ"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content">
</TextView>

使用 FrameLayout 是一个很好的解决方案。如果您在此布局中有更多组件,则必须设置边距以避免重叠。 - Veronnie

23
您已将RelativeLayout设置为"wrap_content",并且将TextView设置为android:layout_alignParentBottom="true",因此它会自动尝试将RelativeLayout拉伸至底部。不要在RelativeLayout中使用这样的依赖关系,因为这可能被视为“循环依赖关系”。
根据RelativeLayout文档的说明:

请注意,RelativeLayout的大小与其子项的位置之间不能存在循环依赖关系。例如,您不能将高度设置为WRAP_CONTENT的RelativeLayout与子项设置为ALIGN_PARENT_BOTTOM

尝试将TextView与父RelativeLayout以外的其他对象对齐,但也要注意避免这个问题:
Circular dependencies, need some help with exact code 或者尝试添加更复杂的内部布局。

3
顺便说一下,我认为在运行时你的代码将被按照你想要的方式显示,即使有 "android:layout_alignParentBottom="true" 的情况也是如此。似乎 Android 在运行时对这种情况进行了一些额外的解析,并正确地显示出来。你应该尝试运行你的应用程序。 - Dirol

1

FrameLayout通常用于将不同的视图叠放在一起(其中最近的子视图位于上一个子视图之上)。在您的情况下,您想将视图放置在一起(上方、下方、左侧、右侧),因此我认为ConstrainLayout更适合,因为它正是它所做的。

RelativeLayout不同的是,您可以将ConstrainLayout的宽度设置为wrap_content,并仍然按照您的意愿排列其子视图,例如:

android:layout_alignParentTop="true"

你可以使用。
grid:layout_constraintTop_toTopOf="parent" 

而不是

android:layout_alignParentBottom="true"

你可以使用。
grid:layout_constraintBottom_toBottomOf="parent"

1
不要在子视图中使用alight_Parent类型属性。
您可以使用带有相应重力的帧布局代替RelativeLayout。
    <FrameLayout
    android:layout_height="wrap_content"
    android:layout_width="wrap_content">
     <TextView
        android:layout_gravity="bottom|right"
        android:text="Hello "
        android:layout_height="wrap_content"
        android:layout_width="wrap_content">

    </TextView>

</FrameLayout>

0

好的答案。现在,如果您没有layout_alignParentBottom="true",但仍然遇到此问题,请注意android:background="@drawable/bkgnd",其中bkgnd是一个大问题。


0

不确定为什么这里所有的答案都建议使用FrameLayout,它是设计用来呈现单个视图或在z轴上分层的视图。OP的问题是一系列垂直堆叠的视图,应该使用LinearLayout


0
我不确定为什么还没有发布一个干净明显的方法来完成这个任务。这个高效的解决方案适用于任何已知高度的视图MyView。
将您的高度为wrap_content的RelativeLayout包装在FrameLayout中:
<!-- width here should constrain RelativeLayout -->
<FrameLayout 
     android:layout_width="@dimen/my_layout_width"
     android:layout_height="wrap_content">

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

     <MyView
        ...
        android:layout_gravity="bottom" />
</FrameLayout>

请注意,FrameLayout底部的视图将位于您的RelativeLayout内容之上,因此您需要在该布局的底部添加填充以容纳它。 如果您希望该视图具有可变高度,则可以通过子类化FrameLayout来添加填充,根据测量的视图高度在代码中进行处理,或者如果您不担心性能问题,即它不是列表视图项,或视图相对较轻,则只需将FrameLayout更改为垂直LinearLayout。


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