Tech and Media Labs
This site uses cookies to improve the user experience.




Android Layout

Jakob Jenkov
Last update: 2014-11-23

In Android the term layout refers to defining how the View components are displayed on the screen relative to each other. A layout is typically defined partly by the View and partly by the ViewGroup which contains the View. As mentioned in View and ViewGroup a ViewGroup is a subclass of View which can itself contain View instances.

You can specify a layout (meaning what ViewGroup to use and what View instances it contains) either programmatically, or via an XML layout file. In most cases it is easiest to use an XML layout file, but in some cases it can be necessary to define your user interface layout programmatically. Therefore this text covers both options.

Layout XML Files

Since layout XML files are the most commonly used layout option, I will cover them first. A layout XML file is an XML file which is stored in your Android project's /app/src/main/res/layout directory.

It is convention to name layout files after what they represent layout for. For instance, a layout file for an activity is normally given a name that starts with actvity_ . A layout file for an activity called MainActivity would thus be named activity_main.xml .

A layout XML file always contain a root element. This root element typically refers to a ViewGroup instance. Here is a layout XML file example with just the root element:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical" android:layout_width="match_parent"
              android:layout_height="match_parent">

</LinearLayout>

Notice how the root element is a LinearLayout element which refers to the LinearLayout ViewGroup subclass.

Inside the root ViewGroup instance the layout file can declare other View and ViewGroup instances. Here is a layout file example that shows the root element from before with a TextView element inside:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical" android:layout_width="match_parent"
              android:layout_height="match_parent">


    <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            >

    </TextView>

</LinearLayout>

Using a Layout File in an Activity

When you have created a layout file you can use it as the content view for an Activity subclass. In other words, you can display the layout defined in the layout file in the activity.

To use a layout file as content view for an activity you call the activity's setContentView() method from inside the activity's onCreate() method. Here is an example:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Notice the parameter passed to setContentView():

R.layout.activity_main

This is a constant generated by Android Studio referring to the layout file activity_main.xml.

Width and Height

When you declare a layout using a layout XML file you have to set values for the two attributes layout_width and layout_height for every ViewGroup and View element. Here is an example of how that looks:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context=".MainActivity">

    <TextView android:text="@string/hello_world"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

</RelativeLayout>

You can use two different values for layout_width and layout_height:

  • match_parent
  • wrap_content

The value match_parent means that the ViewGroup or View should try to match its parent's width or height (minus any padding).

The value wrap_content means that the ViewGroup or View should have a width and height which corresponds to the width and height of the content it contains (meaning no extra space is added above, below or beside).

Padding

Both ViewGroup and View elements in layout files can specify a padding to add around itself. Padding is space where nothing is drawn. Thus, padding makes space between a View or ViewGroup and its neighbour Views or ViewGroups on the screen.

You can set the padding around a View using one of these XML attributes:

  • android:paddingLeft
  • android:paddingRight
  • android:paddingTop
  • android:paddingBottom

Here is the previous layout file example with padding attributes added:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:paddingRight="@dimen/activity_horizontal_margin"
                android:paddingTop="@dimen/activity_vertical_margin"
                android:paddingBottom="@dimen/activity_vertical_margin"
                tools:context=".MainActivity">

    <TextView android:text="@string/hello_world"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content" />

</RelativeLayout>    

The values used in the four different padding attributes reference values defined in the dimensions.xml file which is located at app/src/main/res/values/dimens.xml. The definitions referenced above looks like this:

<resources>
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
</resources>

The value 16dp means 16 device independent pixels, meaning a number of pixels corresponding to 16 pixels on a medium screen resolution device. On a high resolution device the actual number of pixels may thus be 24 or 32 pixels etc. depending on the exact resolution (pixel density actually) of the device.

Programmatic Layout

If you want to create a layout for an activity you can do so programmatically too. You do so by instantiating a View or ViewGroup yourself from inside the activity's onCreate() method. Here is an example:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        TextView textView = new TextView(this);
        textView.setText("Content View");

        setContentView(textView);
    }
}

This example creates a TextView and uses that as content view.

Since an activity can only use a single View as content view, it is common to use a ViewGroup as content view. A ViewGroup is a subclass of View. A ViewGroup can contain multiple View inside it, so using a ViewGroup as content view enables your view to consist of multiple View instances.

Here is an example that uses a LinearLayout (a subclass of ViewGroup) as content view and puts a TextView inside that:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);


        TextView textView1 = new TextView(this);
        textView1.setText("Text View 1");

        TextView textView2 = new TextView(this);
        textView2.setText("Text View 2");

        LinearLayout linearLayout = new LinearLayout(this);
        linearLayout.addView(textView1);
        linearLayout.addView(textView2);

        setContentView(linearLayout);
    }
}

Setting Width and Height Programmatically

If you create a layout programmatically, you will most likely also want to set some layout parameters for the layout. Here is an example that sets the width and height layout parameters of the two TextView instances from the previous example:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);


        TextView textView1 = new TextView(this);
        textView1.setText("Text View 1");
        LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        textView1.setLayoutParams(layoutParams1);

        TextView textView2 = new TextView(this);
        textView2.setText("Text View 2");
        LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        textView2.setLayoutParams(layoutParams2);

        LinearLayout linearLayout = new LinearLayout(this);
        linearLayout.setOrientation(LinearLayout.VERTICAL);
        linearLayout.addView(textView1);
        linearLayout.addView(textView2);

        setContentView(linearLayout);
    }
}

Notice also that the layout orientation on the LinearLayout is set to Layout.VERTICAL meaning the TextView instances will be displayed under each other.

Setting Padding Programmatically

You can set padding programmatically too on a given View using the setPadding() method. Here is an example:

textView2.setPadding(20, 20, 20, 20);

This example sets the padding left, top, right and bottom to 20 pixels. Note: These are real pixels, not device independent pixels.

You can also set padding on a ViewGroup in the same way.

LinearLayout

A LinearLayout is a ViewGroup subclass which will render all View instances added to it linearly, either vertically or horizontally, depending on what orientation. You can create a LinearLayout either in a layout XML file or programmatically.

Here is a LinearLayout example created using layout XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:paddingLeft="@dimen/activity_horizontal_margin"
              android:paddingRight="@dimen/activity_horizontal_margin"
              android:paddingTop="@dimen/activity_vertical_margin"
              android:paddingBottom="@dimen/activity_vertical_margin"
              tools:context=".MainActivity">

    <TextView android:text="@string/hello_world"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content" />

</LinearLayout>

Notice the android:orientation attribute which can be set to either horizontal or vertical.

Here is a LinearLayout example created programmatically:

LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.addView(textView1);
linearLayout.addView(textView2);

RelativeLayout

A RelativeLayout is a ViewGroup which positions View instances displayed inside it either relative to the edges of the parent ViewGroup (which is the RelativeLayout instance itself), or relative to other View instances displayed inside the same RelativeLayout.

The RelativeLayout offers two sets of XML attributes you can use to specify how a given View instance is to be positioned. The first set of attributes position the View relative to its parent RelativeLayout element edges. The second set of attributes position the View relative to another View inside the same RelativeLayout.

Here is the set of attributes used to position a View relative to its parent RelativeLayout edges:

  • android:layout_alignParentLeft
  • android:layout_alignParentRight
  • android:layout_alignParentTop
  • android:layout_alignParentBottom
  • android:layout_alignParentStart
  • android:layout_alignParentEnd
  • android:layout_centerHorizontal
  • android:layout_centerVertical
  • android:layout_centerInParent
  • android:layout_alignWithParentIfMissing

All of these attributes can take a value of either true or false. You can specify more than one, for instance layout_alignParentRight and layout_alignParentBottom will position a View at the bottom right corner of the RelativeLayout.

Here is the set of attributes used to position a View relative to another View inside the same RelativeLayout:

  • android:layout_above
  • android:layout_alignBaseline
  • android:layout_alignBottom
  • android:layout_alignEnd
  • android:layout_alignLeft
  • android:layout_alignRight
  • android:layout_alignStart
  • android:layout_alignTop
  • android:layout_below
  • android:layout_toEndOf
  • android:layout_toLeftOf
  • android:layout_toRightOf
  • android:layout_toStartOf

Most of these attributes are self explanatory. Play around with them to gain a better understanding of how they work.

Here is a RelativeLayout example:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

    <TextView
            android:id="@+id/textview_one"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"

            android:text="One"
            />

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"

            android:layout_above="@id/textview_one"
            android:text="Two"
            />

</RelativeLayout>

This example consists of a layout XML file with a RelativeLayout as root View. Inside the RelativeLayout are two TextView instances. The first TextView element uses the attribute layout_alignParentBottom to position the TextView at the bottom of the RelativeLayout . The second TextView element uses the layout_above attribute to position itself about the View with the id textview_one (which is the first TextView instance).

You can achieve some quite powerful layouts with RelativeLayout once you get acquainted with it.

FrameLayout

A FrameLayout is a ViewGroup subclass which positions the View instances it contains on top of each other like a deck of cards. Thus, the FrameLayout is often used when displaying only a single View inside the FrameLayout, for instance a WebView. However, it is possible to get the FrameLayout to show other views on top of this first View if necessary.

Here is a FrameLayout example using a layout XML file:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="match_parent">

    <WebView
            android:id="@+id/webview_one"
            android:layout_width="match_parent"
            android:layout_height="match_parent"></WebView>

    <TextView
            android:id="@+id/textview_one"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="top|right"

            android:text="One"
            />

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"

            android:layout_gravity="bottom|right"
            android:text="Two"
            />

</FrameLayout>

This example creates a FrameLayout with a WebView and two TextView instances inside. The FrameLayout will display the WebView first and then the two TextView instances on top of the WebView (because they are listed later in the XML file).

Notice how the two TextView instances use the layout_gravity attribute to specify where inside the FrameLayout they are to be displayed.

Jakob Jenkov




Copyright  Jenkov Aps
Close TOC