1. Before you begin
What you'll learn
- How to read and write XML layouts in Android
- How to build the layout for a simple form to take in user text input and choices
What you'll build
- The UI for a tip calculator Android app
What you need
- Android Studio
- A computer with an internet connection to access the Android developer documentation
2. Start the project
Check out the tip calculator on Google: https://www.google.com/search?q=tip+calculator
In this pathway, you'll build a simple version of a tip calculator as an Android app.
Developers will often work in this way—getting a simple version of the app ready and partially functioning (even if it doesn't look very good), and then making it fully functional and visually polished later.
By the end of this codelab, your tip calculator app will look like this:
You will be using these UI elements that are provided by Android:
EditText
- for entering and editing textTextView
- to display text like the service question and tip amountRadioButton
- a selectable radio button for each tip optionRadioGroup
- to group the radio button optionsSwitch
- an on/off toggle for choosing whether to round up the tip or not
Create an Empty Activity project
3. Read and understand XML
strings.xml
.You describe the view hierarchy of UI elements on the screen. For example, a ConstraintLayout
(the parent) can contain Buttons
, TextViews
, ImageViews
, or other views (the children). Remember, ConstraintLayout
is a subclass of ViewGroup
. It allows you to position or size child views in a flexible manner.
Containment hierarchy of an Android app
Each UI element is represented by an XML element in the XML file. Each element starts and ends with a tag, and each tag starts with a <
and ends with a >
. Just as you can set attributes on UI elements using the Layout Editor (design), the XML elements can have attributes, too. Simplified, the XML for the UI elements above might be something like this:
<ConstraintLayout>
<TextView
text="Hello World!">
</TextView>
</ConstraintLayout>

- Open
activity_main.xml
(res > layout > activity_main.xml) - You might notice the app shows a
TextView
with "Hello World!" within aConstraintLayout
, as you have seen in previous projects created from this template.
- Find the options for Code, Split, and Design views in the upper right of the Layout Editor.
- Select the Code view.
This is what the XML in activity_main.xml
looks like:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
There's a lot more going on than in the simplified example, but Android Studio does some things to help make the XML more readable, just as it does with your Kotlin code.
- Notice the indentation. Android Studio does this automatically to show you the hierarchy of elements. The
TextView
is indented because it is contained in theConstraintLayout
. TheConstraintLayout
is the parent, and theTextView
is the child. The attributes for each element are indented to show that they're part of that element. - Notice the color coding—some things are in blue, some in green, and so on. Similar parts of the file are drawn in the same color to help you match them up. In particular, notice that Android Studio draws the start and end of tags of elements in the same color. (Note: the colors used in the codelab may not match what you see in Android Studio.)
XML tags, elements and attributes
Here's a simplified version of the TextView
element so you can look at some of the important parts:
<TextView
android:text="Hello World!"
/>
<TextView
is the start of the tag, and the line with />
is the end of the tag. The line with android:text="Hello World!"
is an attribute of the tag. It represents text that will be displayed by the TextView
. These 3 lines are a commonly used shorthand called an empty-element tag. It would mean the same thing if you wrote it with a separate start-tag and end-tag, like this:<TextView
android:text="Hello World!"
></TextView>
<!-- with attributes, two lines -->
<TextView
android:text="Hello World!" />
ConstraintLayout
element is written with separate start and end tags, because it needs to be able to hold other elements inside it. Here's a simplified version of the ConstraintLayout
element with the TextView
element inside it:<androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:text="Hello World!" />
</androidx.constraintlayout.widget.ConstraintLayout>
View
as a child of the ConstraintLayout
, like a Button
below the TextView
, it would go after the end of the TextView
tag />
and before the end tag of the ConstraintLayout
, like this:<androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:text="Hello World!" />
<Button
android:text="Calculate" />
</androidx.constraintlayout.widget.ConstraintLayout>
More about XML for layouts
- Look at the tag for the
ConstraintLayout
, and notice that it saysandroidx.constraintlayout.widget.ConstraintLayout
instead of justConstraintLayout
like theTextView
. This is becauseConstraintLayout
is part of Android Jetpack, which contains libraries of code which offers additional functionality on top of the core Android platform. Jetpack has useful functionality you can take advantage of to make building apps easier. You'll recognize this UI component is part of Jetpack because it starts with "androidx". - You may have noticed the lines that begin with
xmlns:
, followed byandroid
,app
, andtools
.
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"
The xmlns
stands for XML namespace, and each line defines a schema, or vocabulary for attributes related to those words. The android:
namespace, for example, marks attributes that are defined by the Android system. All of the attributes in the layout XML begins with one of those namespaces.
- Whitespace between XML elements doesn't change the meaning to a computer, but it can help make the XML easier for people to read.
Android Studio will automatically add some whitespace and indenting for readability. You'll learn later how to have Android Studio make sure your XML follows coding style conventions.
- You can add comments to XML, just like you would with Kotlin code. Start
<!--
and end with-->
.
<!-- this is a comment in XML -->
<!-- this is a
multi-line
Comment.
And another
Multi-line comment -->
- Note the first line of the file:
<?xml version="1.0" encoding="utf-8"?>
This indicates that the file is an XML file, but not every XML file includes this.
4. Build the layout in XML
5. Add tip options
Next you'll add radio buttons for the different tip options the user can choose from.
There should be three options:
- Amazing (20%)
- Good (18%)
- Okay (15%)
If you're not sure how to do this, you can do a Google search. This is a great tool that developers use when they're stuck.
- Do a Google search for
radio button android
. The top result is a guide from the Android developers site on how to use radio buttons—perfect!
- Skim through the Radio Buttons guide.
Reading the description, you can confirm that you can use a RadioButton
UI element in your layout for each radio button you need. Furthermore, you also need to group the radio buttons within a RadioGroup
because only one option can be selected at a time.
There is some XML that looks like it would fit your needs. Read through it and see how RadioGroup
is the parent view and the RadioButtons
are child views within it.
- Go back to your layout in Android Studio to add the
RadioGroup
andRadioButton
to your app. - After the
TextView
element, but still within theConstraintLayout
, start typing out<RadioGroup
. Android Studio will provide helpful suggestions to help you complete your XML. - Set the
layout_width
andlayout_height
of theRadioGroup
towrap_content
. - Add a resource ID set to
@+id/tip_options
. - Close the start tag with
>
. - Android Studio adds
</RadioGroup>
. Like theConstraintLayout
, theRadioGroup
element will have other elements inside it, so you might want to move it to its own line. - Constrain the
RadioGroup
below the service question (vertically) and to the start of the parent (horizontally). - Set the
android:orientation
attribute tovertical
. If you wanted theRadioButtons
in a row, you would set the orientation tohorizontal
.
The XML for the RadioGroup
should look like this:
<RadioGroup
android:id="@+id/tip_options"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/service_question">
</RadioGroup>
Add RadioButtons
- After the last attribute of the
RadioGroup
, but before the</RadioGroup>
end tag, add aRadioButton
.
<RadioGroup
android:id="@+id/tip_options"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/service_question">
<!-- add RadioButtons here -->
</RadioGroup>
- Set the
layout_width
andlayout_height
towrap_content
. - Assign a resource ID of
@+id/option_twenty_percent
to theRadioButton
. - Set the text to
Amazing (20%)
. - Close the tag with
/>
.
<RadioGroup
android:id="@+id/tip_options"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/service_question"
app:layout_constraintStart_toStartOf="parent"
android:orientation="vertical">
<RadioButton
android:id="@+id/option_twenty_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Amazing (20%)" />
</RadioGroup>
Now that you've added one RadioButton
, can you modify the XML to add 2 more radio buttons for the Good (18%)
and Okay (15%)
options?
This is what the XML for the RadioGroup
and RadioButtons
looks like:
<RadioGroup
android:id="@+id/tip_options"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/service_question"
app:layout_constraintStart_toStartOf="parent"
android:orientation="vertical">
<RadioButton
android:id="@+id/option_twenty_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Amazing (20%)" />
<RadioButton
android:id="@+id/option_eighteen_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Good (18%)" />
<RadioButton
android:id="@+id/option_fifteen_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK (15%)" />
</RadioGroup>
Add a default selection
Currently, none of the tip options are selected. It would be nice to select one of the radio button options by default.
There's an attribute on the RadioGroup
where you can specify which button should be checked initially. It's called checkedButton
, and you set it to the resource ID of the radio button you want selected
- On the
RadioGroup
, set theandroid:checkedButton
attribute to@id/option_twenty_percent
.
<RadioGroup
android:id="@+id/tip_options"
android:checkedButton="@id/option_twenty_percent"
...
Notice in the Design Editor that the layout has updated. The 20% tip option is selected by default—cool! Now it's starting to look like a tip calculator!
Here is what the XML looks like so far:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
tools:context=".MainActivity">
<EditText
android:id="@+id/cost_of_service"
android:hint="Cost of Service"
android:layout_height="wrap_content"
android:layout_width="160dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:inputType="numberDecimal"/>
<TextView
android:id="@+id/service_question"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="How was the service?"
app:layout_constraintTop_toBottomOf="@id/cost_of_service"
app:layout_constraintStart_toStartOf="parent" />
<RadioGroup
android:id="@+id/tip_options"
android:checkedButton="@id/option_twenty_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/service_question"
app:layout_constraintStart_toStartOf="parent"
android:orientation="vertical">
<RadioButton
android:id="@+id/option_twenty_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Amazing (20%)" />
<RadioButton
android:id="@+id/option_eighteen_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Good (18%)" />
<RadioButton
android:id="@+id/option_fifteen_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK (15%)" />
</RadioGroup>
</androidx.constraintlayout.widget.ConstraintLayout>
6. Complete the rest of the layout
You're on the last part of the layout now. You'll add a Switch
, Button
, and a TextView
to display the tip amount.
Add a Switch for rounding up the tip
Next, you'll use a Switch
widget to allow the user to select yes or no for rounding up the tip.
You want the Switch
to be as wide as the parent, so you might think the width should be set to match_parent
. As noted earlier, you can't set match_parent
on UI elements in a ConstraintLayout
. Instead, you need to constrain the start and end edges of the view, and set the width to 0dp
. Setting the width to 0dp
tells the system not to calculate the width, just try to match the constraints that are on the view.
- Add a
Switch
element after the XML for theRadioGroup
. - As noted above, set the
layout_width
to0dp.
- Set the
layout_height
towrap_content
. This will make theSwitch
view as tall as the content inside. - Set the
id
attribute to@+id/round_up_switch
. - Set the
text
attribute toRound up tip?
. This will be used as a label for theSwitch
. - Constrain the start edge of the
Switch
to the start edge of the parent, and the end to the end of the parent. - Constrain the top of the
Switch
to the bottom of thetip_options
. - Close the tag with
/>
.
It would be nice if the switch was turned on by default, and there's an attribute for that, android:checked
, where the possible values are true
(on) or false
(off).
- Set the
android:checked
attribute totrue
.
Putting that all together, the XML for the Switch
element looks like this:
<Switch
android:id="@+id/round_up_switch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:checked="true"
android:text="Round up tip?"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tip_options" />
Add the Calculate button
Next you'll add a Button
so the user can request that the tip be calculated. You want the button to be as wide as the parent, so the horizontal constraints and width are the same as they were for the Switch
.
- Add a
Button
after theSwitch
. - Set the width to
0dp
, as you did for theSwitch
. - Set the height to
wrap_content
. - Give it a resource ID of
@+id/calculate_button
, with the text"Calculate"
. - Constrain the top edge of
Button
to the bottom edge of the Round up tip?Switch
. - Constrain the start edge to the start edge of the parent and the end edge to the end edge of the parent.
- Close the tag with
/>
.
Here's what the XML for the Calculate Button
looks like.
<Button
android:id="@+id/calculate_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Calculate"
app:layout_constraintTop_toBottomOf="@id/round_up_switch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
Add tip result
You're almost done with the layout! In this step you'll add a TextView
for the tip result, putting it below the Calculate button, and aligned with the end instead of the start like the other UI elements.
- Add a
TextView
with a resource ID namedtip_result
and the textTip Amount
. - Constrain the ending edge of the
TextView
to the ending edge of the parent. - Constrain the top edge to the bottom edge of the Calculate button.
<TextView
android:id="@+id/tip_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/calculate_button"
android:text="Tip Amount" />
Run the app
Great job, especially if this is your first time working with XML!
7. Adopt good coding practices
Extract the strings
You may have noticed the warnings about hard-coded strings. Recall from the earlier codelabs that extracting strings to a resource file makes it easier to translate your app to other languages and to reuse strings. Go through activity_main.xml
and extract all the string resources.
- Click on a string; hover over on the yellow light bulb icon that appears, then click on the triangle next to it; choose Extract String Resource. The default names for the string resources are fine. If you want, for the tip options you can use
amazing_service
,good_service
, andokay_service
to make the names more descriptive.
Now verify the string resources you just added.
- If the Project window isn't showing, click the Project tab on the left side of the window.
- Open app > res > values > strings.xml to see all the UI string resources.
<resources>
<string name="app_name">Tip Time</string>
<string name="cost_of_service">Cost of Service</string>
<string name="how_was_the_service">How was the service?</string>
<string name="amazing_service">Amazing (20%)</string>
<string name="good_service">Good (18%)</string>
<string name="ok_service">Okay (15%)</string>
<string name="round_up_tip">Round up tip?</string>
<string name="calculate">Calculate</string>
<string name="tip_amount">Tip Amount</string>
</resources>
Reformat the XML
Android Studio provides various tools to tidy up your code and make sure it follows recommended coding conventions.
- In
activity_main.xml
, choose Edit > Select All. - Choose Code > Reformat Code.
This will make sure the indenting is consistent, and it may reorder some of the XML of UI elements to group things, for example, putting all the android:
attributes of one element together.
8. Summary
- XML (Extensible Markup Language) is a way of organizing text, made of tags, elements, and attributes.
- Use XML to define the layout of an Android app.
- Use
EditText
to let the user input or edit text. - An
EditText
can have a hint to tell the user what is expected in that field. - Specify the
android:inputType
attribute to limit what type of text the user can input into anEditText
field. - Make a list of exclusive options with
RadioButtons
, grouped with aRadioGroup
. - A
RadioGroup
can be vertical or horizontal, and you can specify whichRadioButton
should be selected initially. - Use a
Switch
to let the user toggle between two options. - You can add a label to a
Switch
without using a separateTextView
. - Each child of a
ConstraintLayout
needs to have vertical and horizontal constraints. - Use "start" and "end" constraints to handle both Left to Right (LTR) and Right to Left (RTL) languages.
- Names of the constraint attributes follow the form
layout_constraint<Source>_to<Target>Of
. - To make a
View
as wide as theConstraintLayout
it's in, constrain the start and end to the start and end of the parent, and set the width to 0dp.
9 Learn more
Below are links to more documentation on the topics covered. You can find all of the documentation for Android Development on developer.android.com. And don't forget you can do a Google search if you get stuck on something.
10. Practice on your own
Do the following:
- Create a different calculator app, like a unit converter for cooking, to convert milliliters to or from fluid ounces, grams to or from cups, and so on. What fields do you need?
0 Comments