Building a menu with LinearLayout
LinearLayout
is probably the simplest layout that Android offers. As the name suggests, all the UI items within it are laid out linearly. You have just two choices – vertical and horizontal. By adding the following line of code (or editing via the Attribute window), you can configure a LinearLayout
to lay things out vertically:
android:orientation="vertical"
You can then (as you could probably have guessed) change "vertical"
to "horizontal"
to lay things out horizontally.
Before we can do anything with LinearLayout
, we need to add one to a layout file. And, as we are building three layouts in this project, we also need a new layout file.
Adding a LinearLayout to the project
In the project window, expand the res
folder. Now right-click the layout
folder and select New. Notice that there is an option for Layout resource file, as shown in the following screenshot:
Select Layout resource file and you will see the New Resource File dialog window:
In the File name field, enter main_menu
. The name is arbitrary, but this layout is going to be our "main" menu that is used to select the other layouts, so the name seems appropriate.
Notice that it has already selected LinearLayout as the Root element option.
Click the OK button, and Android Studio will generate a new LinearLayout
in an XML file called main_menu
and place it in the layout
folder ready for us to build our new main menu UI. Android Studio will also open the UI designer with the palette on the left and the attributes window on the right.
Preparing your workspace
Adjust the windows by dragging and resizing their borders (as you can in most windowed apps) to make the palette, design, and attributes as clear as possible, but no bigger than necessary. This small screenshot shows the approximate window proportions I chose to make designing our UI and exploring the XML as clear as possible. The detail in the screenshot is not important:
Observe that I have made the project, palette, and attribute windows as narrow as possible, yet without obscuring any content. I have also closed the build/logcat window at the bottom of the screen, the result being that I have a nice clear canvas on which to build the UI.
Examining the generated XML
Click on the Text tab and we will have a look at the current state of the XML code that forms our design at this stage. Here is the code so that we can discuss this further:
<?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>
We have the usual starting and closing tags and, as we could have predicted, they are <LinearLayout
and </LinearLayout>
. There is no child element yet, but there are three attributes. We know they are attributes, and not children, of the LinearLayout
, because they appear before the first closing >
. The three attributes that define this LinearLayout
have been highlighted in the previous code for clarity.
The first attribute is android:orientation
, or, more succinctly, we will just refer to the attributes without the android:
part. The orientation
attribute has a value of vertical
. This means that, when we start to add items to this layout, it will arrange them vertically from top to bottom. We could change the value from vertical
to horizontal
and it would lay things out from left to right.
The next two attributes are layout_width
and layout_height
. These determine the size of the LinearLayout
. The value given to both attributes is match_parent
. The parent of a layout is the entire available space. By matching the parent horizontally and vertically, therefore, the layout will fill the entire space available.
Adding a TextView to the UI
Switch back to the Design tab and we will add some elements to the UI.
First, find the TextView in the palette. This can be found in both the Common and Text categories. Left-click and drag the TextView onto the UI, and notice that it sits neatly at the top of the LinearLayout
.
Look at the XML on the Text tab and confirm that it is a child of the LinearLayout
and that it is indented by one tab to make this clear. Here is the code for the TextView
without the surrounding code for the LinearLayout
:
<TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="TextView" />
Notice that it has four attributes: id
, in case we need to refer to it from another UI element or from our Kotlin code; layout_width
is set to match_parent
, which means the that TextView
stretches across the whole width of the LinearLayout
; a layout_height
attribute is set to wrap_content
, which means the that TextView
is precisely tall enough to contain the text within it; and finally, for now, it has a text
element that determines the actual text it will display, and this is currently just set to TextView.
Switch back to the design tab and we will make some changes.
We want this text to be the heading text of this screen, which is the main menu screen. In the attributes window, click the search icon, type text
into the search box, and change the text attribute to Menu
, as shown in the following screenshot:
Tip
You can find any attribute by searching or just by scrolling through the options. When you have found the attribute you want to edit, left-click it to select it and then press the Enter key on the keyboard to make it editable.
Next, find the textSize
attribute using your preferred search technique and set textSize
to 50sp
. When you have entered this new value, the text size will increase.
The sp
stands for scalable pixels. This means that when the user changes the font size settings on their Android device, the font will dynamically rescale itself.
Now, search for the gravity attribute and expand the options by clicking the little arrow indicated in the following screenshot:
Set gravity to center_horizontal, as shown in the following screenshot:
The gravity
attribute refers to the gravity within the TextView
itself, and our change has the effect of moving the actual text inside the TextView
to the center.
Tip
Note that gravity
is different to layout_gravity
. The layout_gravity
property sets the gravity within the layout: in this case, the parent LinearLayout
. We will use layout_gravity
later in this project.
At this point, we have changed the text of the TextView
, increased its size, and centered it horizontally. The UI designer should now look like the following diagram:
A quick glance at the Text tab to see the XML would reveal the following code:
<TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="Menu" android:textSize="50sp" />
You can see the new attributes as follows: gravity
, which is set to center_horizontal
; text, which has changed to Menu
; and textSize
, which is set to 50sp
.
If you run the app, you might not see what you expected. This is because we haven't called setContentView
in our Kotlin code to load the UI. You will still see the blank UI. We will fix this once we have made a bit more progress with the UI.
Adding a multi-line TextView to the UI
Switch back to Design tab, find the Multiline Text in the Text category of the palette, and drag it onto the design just below the TextView
we added a moment ago.
Using your preferred search technique, set text to Select a layout type to view an example. The onClick attribute of each button will call a function which executes setContentView to load the new layout
.
Your layout will now look like the following screenshot:
Your XML will be updated with another child in the LinearLayout
, after the TextView
, that looks like the following code:
<EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="textMultiLine" android:text="Select a layout type to view an example. The onClick attribute of each button will call a function which executes setContentView to load the new layout" />
You can see the details of the UI item and it turns out that the description on the palette of Multiline Text was not entirely obvious as to exactly what this would be. A look at the XML reveals that we have an inputType
attribute, indicating that this text is editable by the user. There is also another attribute that we haven't seen before, and that is ems
. The ems
attribute controls how many characters can be entered per line, and the value of 10
was chosen automatically by Android Studio. However, another attribute, layout_width="match_parent"
, overrides this value because it causes the element to expand to fit its parent; in other words, to cover the whole width of the screen.
When you run the app (in the next section), you will see that the text is, indeed, editable – although, for the purposes of this demo app, it serves no practical purpose.