RelativeLayout is taking fullscreen for wrap_content
Asked Answered
R

8

131

Why does FOOBARZ get layed out all the way at the bottom when no elements are layout_height="fill_parent" in other words, all elements are wrap_content for height? 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>
Reprint answered 26/6, 2011 at 19:34 Comment(4)
Use hierarchyviewer or the Hierarchy View perspective in Eclipse to determine where things are going wrong: developer.android.com/guide/developing/debugging/…Amadis
Where is the hierarchy view perspective inside of eclipse? which screen?Reprint
Window > Open Perspective > Other... -- though I think you already have your answer, courtesy of @alextc.Amadis
@Amadis I've found it, but its blank, how can I actually load a layout into it??Reprint
K
272

From the RelativeLayout doc:

Class Overview

A Layout where the positions of the children can be described in relation to each other or to the parent.

Note that you cannot have a circular dependency between the size of the RelativeLayout and the position of its children. For example, you cannot have a RelativeLayout whose height is set to WRAP_CONTENT and a child set to ALIGN_PARENT_BOTTOM

Class documentation

Which is exactly your case. RelativeLayout can not do that.

Krick answered 26/6, 2011 at 20:15 Comment(7)
So I removed the align_parentBottom and the layout is now only 1/10 the screen as it should be, how can I put FOOBARZ on the bottom of this?Reprint
Just by taking a short look I'd say: Take the FOOBARZ textview, move it to the outer RelativeLayout and set android:layout_below="@id/feed_u". Im not exactly sure if this is what you want tough.Krick
Have you tried assigning a fixed height to the relative layout (e.g. android:layout_height="200dp". This would allow you to use android:layout_alignParentBottom="true"Heldentenor
Note that this can also happen when using a large drawable as a background. To get around it, pull the main content out into a child layout, and make the background a sibling <ImageView> that's behind it.Soult
I noticed that the children are also not allowed to use a layout_height of match_parentNuminous
I would've killed myself had I not seen this answer. RelativeLayout kept being HUGE and taking up the whole screen height, and nothing was ever set to be that big.Darcydarda
This answers why it doesn't work, but doesn't provide a solution.Collinsia
P
58

For those looking for a solution to this, like I did, you can use FrameLayout instead of RelativeLayout.

Then you can set the gravity the intended object to bottom right as below

<TextView
    android:layout_gravity="bottom|right"
    android:text="FOOBARZ"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content">
</TextView>
Pasticcio answered 18/10, 2015 at 15:5 Comment(1)
Use the FrameLayout is great solution. If you have more components in this layout, you have to set margin to avoid overlap.Coward
Z
23

You have set the RelativeLayout to "wrap_content" and the TextView to android:layout_alignParentBottom="true", so it automatically tries to stretch the RelativeLayout to the bottom. Don't use such dependencies with Relative Layout, as it can count as "circular dependencies".

From the docs for RelativeLayout:

Note that you cannot have a circular dependency between the size of the RelativeLayout and the position of its children. For example, you cannot have a RelativeLayout whose height is set to WRAP_CONTENT and a child set to ALIGN_PARENT_BOTTOM.

Try to align your TextView to something other than the parent RelativeLayout, but watch out for this problem as well:
Circular dependencies, need some help with exact code

Alternatively, try to add more sophisticated inner layouts.

Zagreus answered 26/6, 2011 at 20:20 Comment(1)
By the way, I think at the runtime - your code would be displayed as you want, even with the "android:layout_alignParentBottom="true"". It seems, that Android do some additional parsing on this case at the runtime and displays it correctly. You should try to run your app.Zagreus
S
1

Dont use alight_Parent type properties with the child views

You can use frame layout instead of RelativeLayout with respective gravity

    <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>
Scandalize answered 11/4, 2017 at 11:34 Comment(0)
I
1

FrameLayout is usually good for placing different views one on top of each other (where the most recent child is on top of the previous child). In your case, you'd like to place views one next to each other (above, below, start, end), so I think ConstrainLayout fits better because it's exactly what it does.

Unlike RelativeLayout, you'd be able to set the ConstrainLayout width to wrap_content and still arrange its children views as you wish, for example instead of

android:layout_alignParentTop="true"

you can use

grid:layout_constraintTop_toTopOf="parent" 

and instead of

android:layout_alignParentBottom="true"

you can use

grid:layout_constraintBottom_toBottomOf="parent"
Inequality answered 18/1, 2021 at 15:3 Comment(0)
C
0

Good answers. Now if you don't have layout_alignParentBottom="true" and still getting this issue watch out for android:background="@drawable/bkgnd" where bkgnd is a biggie.

Cathee answered 11/1, 2016 at 1:30 Comment(0)
F
0

I'm not sure why the clean and obvious way of accomplishing this hasn't been posted yet. This performant solution works for any View MyView with a known height.

Wrap your RelativeLayout with height wrap_content in a 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>

Just note that the view at the bottom of the FrameLayout will be on top of your RelativeLayout content, so you'll need to add padding to the bottom of that layout to accomodate it. If you want that view to be variable height, you can either Subclass FrameLayout to add padding in code based on the measured view height, or just change the FrameLayout to vertical LinearLayout if you're not worried about the performance, i.e. it's not a listview item, or the views are relatively lightweight.

Fairtrade answered 15/3, 2017 at 19:36 Comment(0)
C
0

Not sure why all the answers here suggest FrameLayout, which is designed to render a single view or views layered in the z axis. OP's problem is a sequence of views stacked vertically, which should be in a LinearLayout.

Collinsia answered 20/4, 2022 at 2:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.