Layouts in Android are used to define the application user interface (UI). Simply put, a layout is a visual template for your application screen that lets you control the properties and positions of your elements. Choosing the right layout will help you improve your app performance and make your UI easier to build. In this topic, you will learn about layouts such as LinearLayout, FrameLayout, and RelativeLayout.
Defining the layout in the XML file
To define the layout that will be used in your Activity, head over to your activity XML file, switch to the Code view mode, and type the layout you need as shown below:
<?xml version="1.0" encoding="utf-8"?>
<!-- Your layout is defined here… -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>
<!-- …and here. Android Studio may correct this one automatically. -->LayoutParams
Before we get on with our layouts, we need to understand what LayoutParams are.
LayoutParams are used by Views to tell their parents how they want to be laid out. The base LayoutParams class describes how big the view wants to be in terms of both width and height. In this case, it can be match_parent, wrap_content, or an exact number. The match_parent fills the parent view completely, wrap_content takes as much space as the contents need, and an exact number specifies the exact size for your View.
There are also subclasses of LayoutParams for the subclasses of ViewGroups like FrameLayout, LinearLayout, and so on. We will discuss them later in this topic.
LinearLayout
This type of layout is simple. All elements in LinearLayout are lined up vertically or horizontally along a single line. There are two main arguments for this layout: android:orientation, which is the main attribute for the layout itself, and the android:layout_weight attribute for the Views. A vertical layout can only have one child per row, and a horizontal layout can only have one row of elements.
For example, this is what LinearLayout looks like with horizontal orientation and weight set to 1:
Try it yourself! Changing the layout_weight attribute of "Button 1" will make it bigger or smaller than the other button.
Here's what that example looks like in the XML file:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button 1" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button 2" />
</LinearLayout>FrameLayout
All child elements of the FrameLayout are usually placed in the top left corner of the screen. Every element of this layout will be drawn on top of the previous one, so it's better to use this layout to hold a single View with height and width attributes set to "match_parent" because otherwise, it can be difficult to control them on different screen sizes.
The only way to control children positioning is by using the layout_gravity and layout_margin attributes. For example, let's place some text on the image. It will look like this:
And here is the code:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView2"
android:layout_width="match_parent"
android:layout_height="400dp"
tools:srcCompat="@tools:sample/avatars" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Hyperskill member" />
</FrameLayout>
Play around with FrameLayout to find more use cases.
RelativeLayout
RelativeLayout contains child views in relative positions, meaning that each element can be positioned relative to another one, or relative to the layout itself (top, bottom, left, right, center). This layout is a little more challenging.
By default, each element is horizontally aligned to the left and vertically to the top of your layout. If you don't change these attributes, each element will be placed on top of the previous one. Let's try to build a simple layout using these RelativeLayout attributes:
android:layout_aboveplaces the bottom edge of the element above the chosen element.android:layout_belowplaces the top edge of the element below the chosen element.android:layout_toStartOfplaces the end edge of this element to the beginning of the chosen element.android:layout_toEndOfplaces the start edge of this element to the end of the chosen element.android:layout_toLeftOfplaces the right edge of the element to the left edge of the chosen element.android:layout_toRightOfplaces the left edge of the element to the right edge of the chosen element.
You can check out all the available attributes on the official Android Developers documentation website.
Here is the RelativeLayout we will build using the attributes above:
After creating all the needed views, we will make all the views relative to each other. In this example, we need to make our TextView with the user name relative to the ImageView.
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:srcCompat="@tools:sample/avatars" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:textStyle="bold"
android:textSize="24dp"
android:layout_toEndOf="@id/imageView"
android:text="John Middleton" />
Done! Now, TextView and ImageView are relative, and our layout should look like this:
Now, we need to add some information about our user. To do this, let's add four more TextViews and make them relative to each other. We will need to use the attributes android:layout_toEndOf and android:layout_below.
<TextView
android:id="@+id/name"
...
android:layout_toEndOf="@id/imageView"
android:text="John Middleton" />
<TextView
android:id="@+id/member"
...
android:layout_toEndOf="@id/imageView"
android:layout_below="@id/name"
android:text="Hyperskill member" />
<TextView
android:id="@+id/userID"
...
android:layout_toEndOf="@id/imageView"
android:layout_below="@id/member"
android:text="Hyperskill ID: 60000001" />
<TextView
android:id="@+id/track"
...
android:layout_toEndOf="@id/imageView"
android:layout_below="@id/userID"
android:text="Track: Kotlin Android developer" />
<TextView
android:id="@+id/activity"
...
android:layout_toEndOf="@id/imageView"
android:layout_below="@id/track"
android:text="Completed 5 topics" />RTL layout support
If you want to reach a bigger audience, your app needs to support Right-To-Left Layout. If you're using attributes like layout_marginLeft/layout_marginRight/paddingLeft/paddingRight or any other Left and Right layout property, you need to replace them with RTL-friendly attributes with Start or End equivalent (for example, layout_marginStart or layout_marginEnd).
You can also just head over to Refactor > Add Right-To-Left (RTL) Support..., and Android Studio will deal with that automatically.
You can also force your layout to be LTR. To do that, add android:layoutDirection="ltr" to your layout in the XML file.
Here's what LTR vs RTL looks like:
Conclusion
In this topic, we have discussed three different layouts. Let's sum it all up:
- You can define the layout in the XML file of your Activity.
- LayoutParams describe what the View or ViewGroup will look like.
- LinearLayout is lined up either vertically or horizontally and has two main arguments:
android:orientationandandroid:layout_weight. - In FrameLayout, all child elements will be drawn on top of each other, which may be difficult to control. The main attributes are
android:layout_gravityandandroid:layout_margin. - RelativeLayout contains children in relative positions; the main attributes are
android:layout_above,android:layout_below,android:layout_toStartOf, andandroid:layout_toEndOf
Now it's time for some practice!