Search code examples
androidandroid-layoutandroid-relativelayout

RelativeLayout not handling "toLeftOf" and/or toRightOf correctly


I have been looking for a solution to the issue with "toLeftOf" and "toRightOf" when using RelativeLayout, but haven't found a real solution or good answer to this behaviour:

Basically, "toLeftOf" isn't working too well.

I have two EditText, and I want an image to be displayed to the left of each EditText. When I try to do that, I get the following result (Eclipse editor):

enter image description here

As you can see, the images are not shown at all. Here is the XML used:

<?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"
    android:layout_marginLeft="30dp"
    android:layout_marginRight="30dp"
    android:layout_marginTop="35dp"
    android:background="#010101"
    android:gravity="center_horizontal"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/login_carNumber"
        style="@style/EditTextDark"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="@string/prompt_carNumber"
        android:inputType="phone"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textCursorDrawable="@null" >

        <requestFocus />
    </EditText>

    <ImageView
        android:id="@+id/login_car_icon"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/user"
        android:layout_toLeftOf="@id/login_carNumber" />

    <EditText
        android:id="@+id/login_password"
        style="@style/EditTextDark"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/login_carNumber"
        android:layout_marginTop="10dp"
        android:hint="@string/prompt_password"
        android:inputType="phone"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textCursorDrawable="@null" >
    </EditText>

    <ImageView
        android:id="@+id/login_lock_icon"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/lock"
        android:layout_toLeftOf="@id/login_password" />

</RelativeLayout>

Firstly, why isn't this working?

If I change the XML, and use "toRightOf" on the EditTexts instead of "toLeftOf" on the images, then I get the follow results:

enter image description here

As you can see, both images are shown, but they are "on top of each other", when the padlock should be on the left side of the second EditText. Here is the XML:

<?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"
    android:layout_marginLeft="30dp"
    android:layout_marginRight="30dp"
    android:layout_marginTop="35dp"
    android:background="#010101"
    android:gravity="center_horizontal"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/login_carNumber"
        style="@style/EditTextDark"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/login_car_icon"
        android:hint="@string/prompt_carNumber"
        android:inputType="phone"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textCursorDrawable="@null" >

        <requestFocus />
    </EditText>

    <ImageView
        android:id="@+id/login_car_icon"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/user" />

    <EditText
        android:id="@+id/login_password"
        style="@style/EditTextDark"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/login_carNumber"
        android:layout_marginTop="10dp"
        android:layout_toRightOf="@+id/login_lock_icon"
        
        android:hint="@string/prompt_password"
        android:inputType="phone"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textCursorDrawable="@null" >
    </EditText>

    <ImageView
        android:id="@+id/login_lock_icon"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/lock" 
        />

</RelativeLayout>

Second question; why is the "padlock" image on top of the first image, and not directly to the left of the second EditText?

If I now add the following line to the last ImageView (the padlock image):

android:layout_below="@+id/login_car_icon"

it is placed correctly, but I think its a "hack" and should not be necessary, right?

So, the last ImageView has the following XML to work:

<ImageView
    android:id="@+id/login_lock_icon"
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:src="@drawable/lock" 
    android:layout_below="@+id/login_car_icon"
    />

Result:

enter image description here

Lastly; why is this needed to make the image to the left of the last EditText?


Solution

  • I have two EditText, and I want an image to be displayed to the left of each EditText. When I try to do that, I get the following result (Eclipse editor):[...]Firstly, why isnt this working?

    The RelativeLayout will do something like this:

    • get the first element, the EditText which is set to fill the width of the parent(and will be positioned starting with the top-left corner(default positioning in a RelativeLayout)), it basically fills all the width of the screen
    • get the ImageView, positioned to the left of the EditText, but as the EditText is placed to start from the left edge of the screen and it fills the entire screen the ImageView will be placed to the left of the EditText outside of the visible screen area

    One way to position the views like you want would be:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="30dp"
        android:layout_marginTop="35dp"
        android:background="#010101"
        android:gravity="center_horizontal"
        android:orientation="vertical" >
    
        <ImageView
            android:id="@+id/login_car_icon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:src="@drawable/user"
            />  
    
        <EditText
            android:id="@+id/login_carNumber"
            style="@style/EditTextDark"
            android:layout_toRightOf="@id/login_car_icon"  
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:hint="@string/prompt_carNumber"
            android:inputType="phone"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textCursorDrawable="@null" >
    
            <requestFocus />
        </EditText>
    
        <EditText
            android:id="@+id/login_password"
            style="@style/EditTextDark"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/login_carNumber"
            android:layout_alignLeft="@id/login_carNumber"
            android:layout_marginTop="10dp"
            android:hint="@string/prompt_password"
            android:inputType="phone"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textCursorDrawable="@null" >
        </EditText>
    
        <ImageView
            android:id="@+id/login_lock_icon"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:src="@drawable/lock"
            android:layout_alignTop="@id/login_password"
        />
    
    </RelativeLayout>
    

    Second question; why is the "padlock" image on top of the first image, and not directly to the left of the second EditText?

    The RelativeLayout will place its children(without rules set on them) starting from the top-left point of the screen. If you don't have rules you end up with staked children.

    Lastly; why is this needed to make the image to the left of the last EditText?

    That is not a hack. You need to tell the RelativeLayout that the second ImageView's position is below the first ImageView.