Previous: [Classes and Inheritance in Kotlin]
1. Preparation
In this article, you'll build the layout for a basic tip calculator app. By the end of this article, the app will have a working interface, but it won't actually be able to calculate tips. Over the next few articles, you'll learn how to get the app working and looking more professional.
prerequisite
- Ability to create and run Android apps based on templates in Android Studio
Learning Content
- How to read and write XML layouts in Android
- How to build a layout for a simple form that accepts user text input and selection
what you will build
- The interface of the Android tip calculator app
required conditions
- A computer with the latest stable version of Android Studio installed
- Connect to the Internet to access the Android Developer Documentation
2. Start the project
In this online course, you'll build a stripped-down Android tip calculator app.
Developers usually take the following development process: prepare a simplified version of the application, implement some functions (even if it does not look very good), then make it fully functional and improve its appearance.
At the end of this article, your tip calculator app will look like this:
You will use the following interface elements provided by Android:
EditText
- for entering and modifying textTextView
- Used to display text such as service questions and tip amountsRadioButton
- Selectable radio buttons corresponding to each tipping optionRadioGroup
- Used to group radio button optionsSwitch
- An on/off toggle to choose whether tips are rounded up
Create an Empty Activity project
- First, create a new Kotlin project in Android Studio using the Empty Activity template.
- Name the app "Tip Time" and set the minimum API level to 19 (KitKat). The package name is com.example.tiptime .
- Click Finish to create the application.
3. Read and understand XML
You'll build your app's layout by modifying the XML that describes the interface , rather than using the layout editor you're already familiar with. For Android developers like you, learning how to use XML to understand and modify interface layouts will be critical.
You'll review and modify the XML files that define the interface layout for this application. XML stands for Extensible Markup Language, which is a way of describing data using text-based documents. Because XML is extensible and flexible, it can be used for many different purposes, including defining the interface layout of an Android application. As you can recall from previous articles, other resources, such as the application's strings, are also defined in an XML file strings.xml
named .
An Android application's interface is built as a containment hierarchy of components (widgets) and screen layouts for those components. Note that these layouts are themselves interface components.
You can describe the view hierarchy of interface elements on the screen. For example, ConstraintLayout
a (parent) can contain Buttons
, TextViews
, ImageViews
or other views (children). Note ConstraintLayout
that ViewGroup
is a subclass of . This enables you to position or resize subviews in a flexible manner.
Containment Hierarchy for Android Apps
Note: The visible interface hierarchy is based on a containment mechanism, where a component contains one or more components. This has nothing to do with the hierarchy of classes and subclasses that you learned about earlier. We sometimes use the terms "parent" and "child", but what we're talking about here is that the parent view (viewgroup) contains child views, which in turn can contain child views.
Each interface element is represented by an XML element in the XML file. Each element begins and ends with a tag, and each tag <
begins and >
ends with . Just as you can set attributes on interface elements using **Layout Editor (Design)**, XML elements can also have attributes. Simplified, the XML for the above interface elements might look like this:
<ConstraintLayout>
<TextView
text="Hello World!">
</TextView>
</ConstraintLayout>
Let's look at a practical example.
- Open
activity_main.xml
( res > layout > activity_main.xml ). - You may notice that, as you've seen in previous projects created from this template, the app displays a "Hello World!"
ConstraintLayout
insideTextView
.
- In the upper right corner of the layout editor, find the Code , Split , and Design views.
- Select the Code view.
activity_main.xml
The XML in should look like this:
<?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>
This is more complex than the simplified example, but Android Studio does a few things to help make the XML easier to read, just like it does for Kotlin code.
- Note the indentation. Android Studio does this automatically to show the hierarchy of elements.
TextView
It is shown indented because it is containedConstraintLayout
within .ConstraintLayout
is the parent,TextView
not the child. Attributes for each element are indented to indicate that they belong to that element. - Note the color coding - some are blue, some are green, etc. Similar parts of the file are drawn in the same color to help you match them. It's important to note that Android Studio paints the beginning and end of element tags in the same color. (Note: The colors used in the article may not match the colors you see in Android Studio.)
XML tags, elements and attributes
Here's a simplified version of TextView
the element so you can see some important parts:
<TextView
android:text="Hello World!"
/>
<TextView
A line of code with is the start of a tag, and />
a line of code with is the end of the tag. android:text="Hello World!"
A line of code with is an attribute of the tag. It represents the text that will be TextView
displayed . These 3 lines of code are a commonly used shorthand called "empty element markup". This is the same as if you wrote code with separate opening and closing tags as follows:
<TextView
android:text="Hello World!"
></TextView>
Typically, we try to minimize the number of lines of code for an empty element tag and combine the end of that tag with the line of code before it. So you might see an empty element tag on two lines of code (or even one if there are no attributes).
<!-- with attributes, two lines -->
<TextView
android:text="Hello World!" />
ConstraintLayout
Elements are written with separate opening and closing tags because it needs to be able to store other elements internally. Here TextView
's ConstraintLayout
a simplified version of the element containing the element:
<androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:text="Hello World!" />
</androidx.constraintlayout.widget.ConstraintLayout>
If you want to add View
another ConstraintLayout
child of the , such as TextView
the one below Button
, you can place TextView
it />
after the tag and before the closing tag ConstraintLayout
of the , like this:
<androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:text="Hello World!" />
<Button
android:text="Calculate" />
</androidx.constraintlayout.widget.ConstraintLayout>
For more information on the XML used to create layouts
- Looking
ConstraintLayout
at the markup for , you'll notice that it saysandroidx.constraintlayout.widget.ConstraintLayout
, rather than justTextView
likeConstraintLayout
. This is becauseConstraintLayout
is part of Android Jetpack, which contains code libraries that provide additional functionality on top of the Android core platform. Jetpack includes many useful features that you can use to build applications more easily. You'll find this interface component is part of Jetpack because it starts with "androidx". - You may have noticed the lines of code that
xmlns:
begin with , followed byandroid
, andapp
.tools
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"
xmlns
Represents an XML namespace, and each line of code defines a schema, or vocabulary of attributes associated with those words. For example, android:
namespaces mark attributes defined by the Android system. All attributes in the layout XML start with one of these namespaces.
- Adding whitespace between XML elements doesn't change their meaning to computers, but it helps users read XML more easily.
Android Studio automatically adds some whitespace and indentation to improve readability. You'll learn later how to make Android Studio ensure that your XML follows coding style guidelines.
- You can annotate XML just as you annotate Kotlin code. Comments should
<!--
start with 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 contains this line of code.
Note: If there is a problem with your app's XML, Android Studio will flag the problem by drawing the text in red. If you hover over the red text, Android Studio will display more information about the issue. If the problem is not obvious, look at the indentation and color coding, they may help you find the source of the problem.
Fourth, use XML to build the layout
-
Still
activity_main.xml
in , switch to the Split screen view to see the XML next to the Design Editor . In Design Editor , you can preview the interface layout.
-
It's up to you which view to use depending on your personal preference, but for this article, use the Split view so you can see both the XML you modified and the changes made by those modifications in the Design Editor .
-
Try clicking on different lines of code, such as first clicking on a line of code
ConstraintLayout
under and then clicking onTextView
a line of code under , and you will notice that the corresponding view in the Design Editor is selected. Vice versa, for example, if you click in the Design EditorTextView
, the corresponding XML is highlighted.
removeTextView
- You don't need it now
TextView
, so delete it. Be sure to<TextView
delete/>
everything from to the closing tag .
<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" />
All that remains in the file is ConstraintLayout
:
<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">
</androidx.constraintlayout.widget.ConstraintLayout>
ConstraintLayout
Add 16dp of padding to to prevent the interface from being pushed to the edge of the screen.
Padding is similar to margin, but it adds space to the inside ConstraintLayout
of the instead of outside.
<androidx.constraintlayout.widget.ConstraintLayout
...
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity">
Note: For brevity, some code snippets in this article do not show the full content. Code that has not changed or is not relevant to the current step will be indicated with an ellipsis (3 consecutive dots...)) so that you can focus on the most important parts of the code.
Add a "Cost of Service" text field
In this step, you'll add UI elements that allow users to enter charges for services in your app. You'll use EditText
the element , which enables users to enter or modify text in the application.
- Check out
EditText
the documentation , and examine the sample XML. ConstraintLayout
Find the white space between the opening and closing tags of the .- Copy the XML from the documentation and paste it into the corresponding blank space within your layout in Android Studio.
At this point, your layout file should look like this:
<?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"
android:padding="16dp"
tools:context=".MainActivity">
<EditText
android:id="@+id/plain_text_input"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:inputType="text"/>
</androidx.constraintlayout.widget.ConstraintLayout>
You may not fully understand the code above, but we'll cover it in the steps below.
- Note that
EditTex
t is underlined in red. - Hover over here and you'll see an error that the view is not constrained, similar to what you saw in the previous codelab. As mentioned earlier,
ConstraintLayout
the children of a layout need to be constrained so that the layout knows how to arrange them.
- Add these constraints
EditText
to anchor it to the upper left corner of the parent.
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
If you're writing code in English or another left-to-right (LTR) language, the starting edge is on the left. But some languages, such as Arabic, are written right-to-left (RTL), so the starting edge is on the right. This is why the constraint uses "start", so that it can be used with LTR or RTL languages. Also, use "end" for the constraint, not "right".
Note: The name of the constraint should follow
layout_constraint<Source>_to<Target>Of
the format , where<Source>
refers to the current view.<Target>
It refers to the edge of the target view (which can be the parent container or other views) to which the current view is constrained.
After adding the new constraint, EditText
the element will look like this:
<EditText
android:id="@+id/plain_text_input"
android:layout_height="wrap_content"
android:layout_width="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:inputType="text"/>
Checking the EditText Attributes
Please double-check any EditText
attributes to make sure it works in your application.
- Locate the attribute set
@+id/plain_text_input
toid
. id
Change the property to a more appropriate name@+id/cost_of_service
.
Note: The resource ID is the element's unique resource name. When you add
View
or , Android Studio automatically assigns them resource IDs. When you enter it manually in XML, you need to explicitly declare the resource ID yourself. New view IDs in the XML file must be defined with@+id
the prefix , which causes Android Studio to add the corresponding ID as a new resource ID.Choose descriptive names for your resources so you know what they are for, but use all lowercase letters and use underscores to separate multiple words.
When you refer to resource IDs in application code, use
R.<type>.<name>
the format , egR.string.roll
. ForView ID
,<type>
forid
, for exampleR.id.button
.
- View
layout_height
properties . This property is set towrap_content
, which means it will be as tall as its contents. This setting is fine as there is only 1 line of text. - View
layout_width
properties . This property is set tomatch_parent
, but you cannot set itConstraintLayout
on children ofmatch_parent
. Also, the text field doesn't need to be that wide. Set it to160dp
this fixed width, which should be enough for the user to enter the service fee.
- Note
inputType
the attribute , which is a new attribute. The value of this property is"text"
, which means that the user can enter arbitrary text characters (alphabetic characters, symbols, etc.) into the field on the screen.
android:inputType="text"
However, you need the user to enter only numbers EditText
in the , since the field represents a monetary value.
- Clear
text
the word, but keep the English quotes. - Start typing at that location
number
. After typing "n", Android Studio displays a list of possible completions that include "n".
- Select
numberDecimal
, which will limit the entry to numbers with a decimal point.
android:inputType="numberDecimal"
For other input type options, see Specifying input method types in the developer documentation .
There is one other change that needs to be made because showing some hints will help the user figure out what to enter in this field.
hint
Add the attributeEditText
to the to describe what the user should enter in this field.
android:hint="Cost of Service"
You'll see that the Design Editor is updated accordingly.
- Run the app in the simulator. The display should look like this:
Great! It doesn't do much yet, but you've got a good start and some tweaks to the XML. The XML you use to create the layout should look like this.
<?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"
android:padding="16dp"
tools:context=".MainActivity">
<EditText
android:id="@+id/cost_of_service"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:hint="Cost of Service"
android:inputType="numberDecimal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Adding a Service Question
In this step, you will add a question prompt "How was the service?" TextView
. Try typing this instead of copy/pasting. The suggestions provided by Android Studio may help you.
-
EditText
After the end of tag/>
, add a new line of code and start typing <TextView. -
Choose from the suggestions
TextView
, and Android Studio will automaticallyTextView
addlayout_width
andlayout_height
attributes for . -
For both attributes, select both
wrap_content
, since you only need to be the same sizeTextView
as the text content in it.
-
Add
text
a property , set it to"How was the service?"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="How was the service?"
- End the tag with />.
- Note that
Design Editor
in , overlapsTextView
with .EditText
That doesn't look right, so you next need to TextView
add constraints on the . Think about what constraints you need. TextView
Where should it be located horizontally and vertically? You can get help by viewing app screenshots.
Vertically, you need to be TextView
below the "Cost of Service" text field. Horizontally, you need to align TextView
with the parent view's starting edge.
TextView
Add a horizontal constraint to constrain its start edge to the parent view's start edge.
app:layout_constraintStart_toStartOf="parent"
- To
TextView
add a vertical constraint,TextView
constrain the top edge of to be the bottom edgeView
of .
app:layout_constraintTop_toBottomOf="@id/cost_of_service"
Note that @id/cost_of_service
there is no plus sign in because the corresponding ID is already defined.
The app doesn't look perfect, but leave that alone for now. You just need to make sure that all necessary components are present on the screen and functioning properly. You'll modify its appearance in a subsequent article.
TextView
Add resource id on . You'll need to reference this view later when you add more views and make them constrain each other.
android:id="@+id/service_question"
At this point, your XML should look like this.
<?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"
android:padding="16dp"
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_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cost_of_service"/>
</androidx.constraintlayout.widget.ConstraintLayout>
5. Add tip option
Next, you'll add radio buttons for users to choose from different tipping options.
The following three options should be provided:
- Awesome (20%)
- very good (18%)
- Good (15%)
If you're not sure how to do this, you can do a Google search. Developers can use this powerful tool when they get stuck.
-
Search on Google
radio button android
. The top search result is from the Android Developers site with a guide on how to use the radio buttons, great!
-
Browse the radio button guide .
By reading the instructions, you can be sure that you can use oneRadioButton
interface . Also, you need to group the radio buttonsRadioGroup
in since only one option can be selected at a time.
There is some XML that seems to fit your needs. Read on to learn RadioGroup
how to be a parent view, and RadioButtons
a subview within it.
-
Go back to your layout in Android Studio, add
RadioGroup
andRadioButton
to your app. -
TextView
After the element (but stillConstraintLayout
within ), begin typing<RadioGroup
. Android Studio will provide some practical suggestions to help you complete the modification of the XML.
-
RadioGroup
Set thelayout_width
and of to .layout_height
wrap_content
-
Add a resource id and set it to
@+id/tip_options
. -
>
End the start tag with . -
Android Studio will add it
</RadioGroup>
.ConstraintLayout
Like ,RadioGroup
the element will contain other elements, so you may need to move it to its own line.
-
RadioGroup
Constrains to be below the service question (in the vertical direction), and at the start of the parent view (in the horizontal direction). -
android:orientation
Set the property tovertical
. If you're adding in a rowRadioButtons
, you should set the screen orientation tohorizontal
.
RadioGroup
The XML 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 RadioButton
RadioGroup
After the last attribute of the , but</RadioGroup>
before the closing 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
layout_width
andlayout_height
towrap_content
. RadioButton
Assign a resource ID to@+id/option_twenty_percent
.- Set the text to
Amazing (20%)
. />
End 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 Good (18%)
to Okay (15%)
add 2 more radio buttons for the and options?
RadioGroup
RadioButtons
The XML for and should look like this:
<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 Default Selection
Currently, none of the tipping options are selected. It is best to select a radio button option by default.
RadioGroup
There is a property on that allows you to specify which button should be initially selected. The property is called checkedButton
and you need to set it to the resource ID of the radio button you want to select.
RadioGroup
In ,android:checkedButton
set the property to@id/option_twenty_percent
.
<RadioGroup
android:id="@+id/tip_options"
android:checkedButton="@id/option_twenty_percent"
...
Note that in Design Editor
the , the layout has been updated accordingly. The 20% tip option is selected by default, awesome! Now, it's starting to look a bit like a tip calculator!
The XML should currently look like this:
<?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"
android:padding="16dp"
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 now need to handle the last part of the layout. You need to add a Switch
, a Button
, and a TextView
to display the tip amount.
Add switch to round tip up
Next, you'll use Switch
the widget to give the user the option to round up the tip.
You want the Switch
to be as wide as the parent, so consider setting the width to match_parent
. As mentioned earlier, you cannot set for UI elements ConstraintLayout
in match_parent
. Instead, you need to constrain the start and end edges of that view, and set the width to 0dp
. If you set the width to 0dp
, you are telling the system not to calculate the width and just try to match the constraints set on the view.
Note: You cannot
match_parent
use with any view in a ConstraintLayout. Use instead0dp
, which means matching constraints are required.
- Add a element after the XML
RadioGroup
for .Switch
- As above,
layout_width
set to0dp
. layout_height
Set towrap_content
. This will makeSwitch
the view as tall as its contents.id
Set the property to@+id/round_up_switch
.text
Set the property toRound up tip
?. This will be used as the labelSwitch
for the .Switch
Constrains the start edge to betip_options
the start edge of and its end edge to be the parent's end edge.Switch
Constrains the top of totip_options
the bottom of ./>
End the tag with .
It is best to make the switch on by default, android:checked
and this , and its possible values are true
(on) or false
(off).
android:checked
Set the property totrue
.
Putting it all together, Switch
the element's XML should look 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="@id/tip_options"
app:layout_constraintTop_toBottomOf="@id/tip_options" />
Note: If you hover over
Switch
the element , you'll see a suggestion in Android Studio that says "UseSwitchCompat
from AppCompat or from Material library."SwitchMaterial
You can ignore the warning until you implement this suggestion in a subsequent codelab on how to build a tip calculator app.
Adding a "Calculate" Button
Next, you need to add one Button
so users can request a tip be calculated. You want the button to be as wide as the parent so that its horizontal constraints and width are the same as Switch
the .
Switch
Add one after theButton
.Switch
Set the width to in the same way you set the width to0dp
.- Set the height to
wrap_content
. - Give it the resource id
@+id/calculate_button
along with the text"Calculate"
. - Constrains the top edge
Button
of the toRound up tip?
Switch
the bottom edge of the . - Constrains the start edge to the parent's start edge and the end edge to the parent's end edge.
/>
End the tag with .
CalculateButton
's XML should look like this:
<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 calculation result
Your layout is almost done! In this step, you'll add one for the tip calculation TextView
, place it under the Calculate button, and align it to the end edge instead of the start edge like other UI elements.
- Add a resource with ID named
tip_result
andTip Amount
textTextView
. TextView
Constrains the end edge of the to the parent's end edge.- Constrains the top edge to the bottom edge of
Calculate
the 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 application. The display should look like the screenshot below.
marvelous! Especially if you're new to XML!
Note that the app may not look exactly like the screenshots, as the templates may have changed in later versions of Android Studio. The Calculate button doesn't do anything yet, but you can enter a fee, choose a tip percentage, and toggle an option to choose whether to round up the tip. In the next article, you'll take steps to get the Calculate button working, so be sure to check back!
7. Adopt standardized coding practices
extract string
You may have noticed the warning about hardcoded strings. As you can see from previous articles, extracting strings into resource files makes it easier to translate your app into other languages, and also allows strings to be reused. Browse activity_main.xml
and extract all string resources.
- Click on a string; hover over the yellow light bulb icon that appears, and click the triangle next to it; select Extract String Resource . There is no problem with the default name of the string resource. For tip options, you can use
amazing_service
, ,good_service
andokay_service
to make the name more descriptive, if desired.
Now, verify the string resource you just added.
- If the Project window is not displayed , click the Project tab on the left side of the window.
- Open app > res > values > strings.xml in turn to view all interface 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 organize your code and ensure it follows recommended coding practices.
activity_main.xml
In , choose Edit > Select All .- Choose Code > Reformat Code .
This ensures consistent indentation, and it may reorder some XML for interface elements for grouping purposes (for example, bringing allandroid:
attributes ).
Eight, solution code
res/layout/activity_main.xml
<?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"
android:padding="16dp"
tools:context=".MainActivity">
<EditText
android:id="@+id/cost_of_service"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:hint="@string/cost_of_service"
android:inputType="numberDecimal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/service_question"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/how_was_the_service"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cost_of_service" />
<RadioGroup
android:id="@+id/tip_options"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkedButton="@id/option_twenty_percent"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/service_question">
<RadioButton
android:id="@+id/option_twenty_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/amazing_service" />
<RadioButton
android:id="@+id/option_eighteen_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/good_service" />
<RadioButton
android:id="@+id/option_fifteen_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ok_service" />
</RadioGroup>
<Switch
android:id="@+id/round_up_switch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/round_up_tip"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/tip_options"
app:layout_constraintTop_toBottomOf="@id/tip_options" />
<Button
android:id="@+id/calculate_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/calculate"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/round_up_switch" />
<TextView
android:id="@+id/tip_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tip_amount"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/calculate_button" />
</androidx.constraintlayout.widget.ConstraintLayout>
res/values/strings.xml
<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>
Nine. Summary
- XML (Extensible Markup Language) is a way of organizing text and consists of tags, elements, and attributes.
- Use XML to define the layout of an Android application.
- Use
EditText
to allow users to enter or modify text. EditText
A prompt is generated telling the user what to enter in the field.- Specify
android:inputType
the attribute to restrictEditText
what type of text the user can enter in the field. - Use
RadioButtons
to create a list of mutually exclusive options, and useRadioGroup
to group them. RadioGroup
Can be arranged vertically or horizontally, and you can specify which should be initially selectedRadioButton
.- Use
Switch
to toggle the user between the two options. - You can add tags to without using a
TextView
separate .Switch
ConstraintLayout
Each child of must have vertical and horizontal constraints.- Use the "start" and "end" constraints to handle languages written left-to-right (LTR) and right-to-left (RTL).
- The names of constraint properties should follow
layout_constraint<Source>_to<Target>Of
the format . - To
View
makeConstraintLayout
the as wide as the it's in, constrain its start edge to the parent's start edge, its end edge to the parent's end edge, and set the width to 0dp.
10. Learn more
Follow the links below to view more documentation on the topics covered. You can find all the documentation on Android development at developer.android.com . Also, don't forget to Google it if you get stuck.
TextView
EditText
- Specify input method type
- Radio Button Guidelines
RadioButton
RadioGroup
Switch
-ConstraintLayout
Eleven, self-practice
Note: Practice as needed. You can take this opportunity to practice what you have learned in this article.
Please do the following exercises:
- Create a different calculator app, such as a cooking unit of measure converter, to convert between milliliters and fluid ounces, grams and cups, and so on. Which fields do you need?
Next:【Calculate tip】