views:

28

answers:

1

I'm trying to use RelativeLayout to display a map tile, surrounded by directional buttons, in a simple dialog.

I've tried a few variations, but inevitably, some of my buttons are missing.

In this version of the example, the up and left buttons are missing. If I declare the up button first and place the tile button relative to it, then up shows. Do RelativeLayouts require the topmost widget to be declared first? Guess not, there would be no use for layout_above then...

I can't post images (low rep), but you can view the result 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="fill_parent"
    >

<ImageView
        android:id="@+id/tile"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5px"
        android:layout_centerInParent="true"
        android:src="@drawable/loading"
        />

<Button
        android:id="@+id/up"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/tile"
        android:layout_centerHorizontal="true"
        android:drawableLeft="@drawable/up"
        />
<Button
        android:id="@+id/left"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@id/tile"
        android:layout_centerVertical="true"
        android:drawableLeft="@drawable/left"
        />
<Button
        android:id="@+id/right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/tile"
        android:layout_centerVertical="true"
        android:drawableLeft="@drawable/right"
        />
<Button
        android:id="@+id/down"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tile"
        android:layout_centerHorizontal="true"
        android:drawableLeft="@drawable/down"
        />

<Button
        android:id="@+id/in"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tile"
        android:layout_alignParentLeft="true"
        android:text="@string/test_in"
        />
<Button
        android:id="@+id/out"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tile"
        android:layout_alignParentRight="true"
        android:text="@string/test_out"
        />
</RelativeLayout>
A: 

The widgets actually do need to be declared before they can be referenced, at least prior to Android 2.2. You can try something like the below, I'm not certain of how you wanted the In/Out buttons placed, but this should give a general idea:

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    > 
<Button 
    android:id="@+id/up" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true" 
    android:drawableLeft="@drawable/up" 
    /> 
<Button 
    android:id="@+id/left" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentLeft="true"
    android:layout_centerVertical="true" 
    android:drawableLeft="@drawable/left" 
    /> 
<Button 
    android:id="@+id/right" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true" 
    android:drawableLeft="@drawable/right" 
    /> 
<Button 
    android:id="@+id/down" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true" 
    android:drawableLeft="@drawable/down" 
    /> 
<Button 
    android:id="@+id/in" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true" 
    android:text="@string/test_in" 
    /> 
<Button 
    android:id="@+id/out" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true" 
    android:text="@string/test_out" 
    />
<ImageView 
    android:id="@+id/tile" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_margin="5px" 
    android:layout_above="@id/down"
    android:layout_toRightOf="@id/left"
    android:layout_toLeftOf="@id/right"
    android:layout_below="@id/up"
    android:layout_gravity="center"
    android:src="@drawable/loading" 
    /> 
</RelativeLayout>

Basically, you want to place the arrows and in/out buttons first, aligned with the parent (the main window). Then, use above/below/RightOf/LeftOf to define the edges of the map tile. I'm not sure offhand whether ImageView uses layout_gravity or just gravity (I always get them confused), but if not one, just try the other. This is from the top of my head - untested - so let me know if something quirky happens.

EDIT: Second suggestion. This is more similar to yours (I wasn't thinking about the map not being fill_parent), but using gravity instead of centerHorizontal, and using just layout_above/below/left/right instead of alignParent**.

<RelativeLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    >   
<ImageView  
    android:id="@+id/tile"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:layout_margin="5px"  
    android:gravity="center"
    android:src="@drawable/loading"  
    />  
<Button  
    android:id="@+id/up"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:layout_above="@id/tile"
    android:gravity="center_horizontal"  
    android:drawableLeft="@drawable/up"  
    />  
<Button  
    android:id="@+id/left"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:layout_toLeftOf="@id/tile"
    android:gravity="center_vertical"
    android:drawableLeft="@drawable/left"  
    />  
<Button  
    android:id="@+id/right"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:layout_toRightOf="@id/tile"
    android:gravity="center_vertical"
    android:drawableLeft="@drawable/right"  
    />  
<LinearLayout
    android:id="@+id/bottom"
    android:orientation="horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/tile"
    android:gravity="center_horizontal"
    >   
<Button  
    android:id="@+id/out"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:text="@string/test_out"  
    android:padding="5dp"
    />
<Button  
    android:id="@+id/down"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:drawableLeft="@drawable/down"  
    android:padding="5dp"
    /> 
<Button  
    android:id="@+id/in"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    android:text="@string/test_in"  
    android:padding="5dp"
    />
</RelativeLayout> 
kcoppock
A useful suggestion, since it caused me to rethink how I should analyze RelativeLayouts... but it also causes the dialog that uses the layout to go full-screen (a combination of the necessary `fill_parent` on the layout and the fact that the directional buttons are stuck to the sides).
Pierre-Luc Paour
This is the resulting screenshot: http://emberapp.com/paour/images/kcoppock
Pierre-Luc Paour
Ah, that does make sense. Having the screenshot is useful though. Did you try changing the RelativeLayou to wrap_content? I don't think that will solve the problem, but it's worth trying. I'll see if I can't come up with a better solution a little later on.
kcoppock
Can't use `wrap_content` and `alignParentRight`. See the note at the top of the RelativeLayout documentation: 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.
Pierre-Luc Paour
Yeah, that's what I was thinking, that makes sense as well. Wish I had Eclipse here at work so I could test some things. I'm going to edit in another suggestion.
kcoppock
Thanks for the new suggestion. However, I don't believe `android:gravity` is allowed with `RelativeLayout`. And neither is `android:layout_gravity`. Or at least that's what my IDE's autocomplete is telling me.
Pierre-Luc Paour