Thursday, January 10, 2013

RelativeLayout for dummies

When I started working with Android I was doing strictly LinearLayouts, but they get complicated and ugly very fast. It's analogous to rowspans and colspans in HTML tables, only messier.  Then I learned about RelativeLayout.

It's slick in that you can declare all your elements in (pretty  much) a single RelativeLayout instead of having a zillion child LinearLayouts.  All you have to do is say where an element should appear in relation to another element. To do this you have

layout_alignParentRight, ~Top, ~Left and ~Bottom to anchor your element to the layout itself.  These are ="true" (or not declared at all, I suppose).

layout_toLeftOf and ~RightOf, and layout_above and ~below for positioning relative to other elements.  The argument is the id of the other element, e.g. ="@+id/titleBox"

Things learned: the LinearLayout urge is to declare elements in order of appearance from top to bottom.  Don't do it that way.  Organize by items that are going to stay a fixed size and location versus items that you want to stretch to fill the remaining space.

So I'm laying out elements for a basic media control. It has a TextView for the title of the clip, a ProgressBar, an ImageButton that will later be coded to toggle between play and pause images, and two more TextViews, one to display the total length of the clip and one for the current time position.

I want the title on the left, the play/pause button on the right, and the progress bar to stretch to fill any space in between.

So the first two things I declare are the title and the button.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@color/offwhite">
    <ImageButton
            android:id="@+id/btnPlay"
            android:src="@drawable/playbutton"
            android:layout_alignParentRight="true"
            android:scaleType="fitEnd"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:paddingRight="10dp"
            android:background="@null"
            />

   <TextView
            android:id="@+id/songTitle"
            android:textColor="@color/d_gray"
            android:textSize="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:paddingLeft="10dp"
            android:paddingTop="22dp"
            android:text="clip title"
            />

Then we'll jam the seekbar in between, with a little padding to give it some distance from the other elements.
    <SeekBar
            android:id="@+id/songProgressBar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/btnPlay"
            android:layout_toRightOf="@+id/songTitle"
            android:paddingTop="20dp"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            />
The last two textviews are anchored to the seekbar itself.  They have the same left and right padding as the seekbar.
   <TextView
            android:id="@+id/songCurrentDurationLabel"
            android:textColor="@color/d_gray"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignLeft="@+id/songProgressBar"
            android:layout_below="@+id/songProgressBar"
            android:paddingLeft="15dp"
            android:text="current time"
            />
    <TextView
            android:id="@+id/songTotalDurationLabel"
            android:textColor="@color/d_gray"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignRight="@+id/songProgressBar"
            android:layout_below="@+id/songProgressBar"
            android:paddingRight="15dp"
            android:text="total time"
            />

This is so much cleaner than having about 3 nested levels of LinearLayouts.

No comments:

Post a Comment