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
TextViewwith "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
TextViewis indented because it is contained in theConstraintLayout. TheConstraintLayoutis the parent, and theTextViewis 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.ConstraintLayoutinstead of justConstraintLayoutlike theTextView. This is becauseConstraintLayoutis 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
RadioGroupandRadioButtonto your app. - After the
TextViewelement, but still within theConstraintLayout, start typing out<RadioGroup. Android Studio will provide helpful suggestions to help you complete your XML.
- Set the
layout_widthandlayout_heightof theRadioGrouptowrap_content. - Add a resource ID set to
@+id/tip_options. - Close the start tag with
>. - Android Studio adds
</RadioGroup>. Like theConstraintLayout, theRadioGroupelement will have other elements inside it, so you might want to move it to its own line.
- Constrain the
RadioGroupbelow the service question (vertically) and to the start of the parent (horizontally). - Set the
android:orientationattribute tovertical. If you wanted theRadioButtonsin 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_widthandlayout_heighttowrap_content. - Assign a resource ID of
@+id/option_twenty_percentto 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:checkedButtonattribute 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
Switchelement after the XML for theRadioGroup. - As noted above, set the
layout_widthto0dp. - Set the
layout_heighttowrap_content. This will make theSwitchview as tall as the content inside. - Set the
idattribute to@+id/round_up_switch. - Set the
textattribute toRound up tip?. This will be used as a label for theSwitch. - Constrain the start edge of the
Switchto the start edge of the parent, and the end to the end of the parent. - Constrain the top of the
Switchto 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:checkedattribute 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
Buttonafter 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
Buttonto 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
TextViewwith a resource ID namedtip_resultand the textTip Amount. - Constrain the ending edge of the
TextViewto 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_serviceto 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
EditTextto let the user input or edit text. - An
EditTextcan have a hint to tell the user what is expected in that field. - Specify the
android:inputTypeattribute to limit what type of text the user can input into anEditTextfield. - Make a list of exclusive options with
RadioButtons, grouped with aRadioGroup. - A
RadioGroupcan be vertical or horizontal, and you can specify whichRadioButtonshould be selected initially. - Use a
Switchto let the user toggle between two options. - You can add a label to a
Switchwithout using a separateTextView. - Each child of a
ConstraintLayoutneeds 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
Viewas wide as theConstraintLayoutit'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