Previous: [Classes and Object Instances in Kotlin]
1. Preparation
In this article, you'll create a Dice Roller Android app where the user taps to Button
roll the dice . The result of the dice roll will be displayed TextView
in .
You'll use the layout editor in Android Studio to build your app's layout, then write Kotlin code to handle what happens Button
when .
prerequisite
- Learn how to create and run a "Hello, World!" app in Android Studio.
- Familiarize yourself with how to use it in your application
TextViews
. - Learn how to
布局编辑器
modify propertiesTextView
of . - Learn how to extract text into string resources, making it easier to translate apps and reuse strings.
- Learn the basics of Kotlin programming
Learning Content
How to add a Button to an Android application.
How to add a Button click behavior to your application.
How to open and modify the application's Activity code.
How to display Toast messages.
How to update the content of the TextView while the app is running.
what you will build
- A Dice Roller Android app that has a for rolling dice
Button
and updates the text on the screen based on the result of the roll.
required tools
- A computer with Android Studio installed.
Here's what your built app will look like after completing this article.
2. Set up the application
Create an empty Activity project
- If you already have an existing project open in Android Studio, go to File > New > New Project. … to open the Create New Project screen.
- In Create New Project , create a new Kotlin project using the Empty Activity template.
- Name the app "Dice Roller" and set the minimum API level to 19 (KitKat).
- Run the new application and the interface should look like this.
3. Create a layout for the application
Open the layout editor
- In the Project window, double click
activity_main.xml
( app > res > layout > activity_main.xml ) to open it. You should see the layout editor showing just "Hello World" in the center of the appTextView
.
Next, you'll add one to your app Button
. Button
Is an interface (UI) element in Android that a user can tap to perform an action.
In this task you will TextView
add below "Hello World" Button
. LocatedTextView
within the same as , a ConstraintLayout is one .Button
ConstraintLayout
ViewGroup
When present ViewGroup
in a Views
, Views
is considered a child ViewGroup
of . In your application, TextView
and Button
will be considered ConstraintLayout
children of the parent .
will Button
be added as ConstraintLayout
a child of the existing in the app.
Note: As with family trees, in a view hierarchy, parent views can themselves be subviews, and subviews can be the parent of other subviews.
Add a Button to the layout
Button
Drag from the Palette into the Design view and place itTextView
below "Hello World".
- In the Component Tree below the Palette , verify that and are listed under (as children of ).
Button
TextView
ConstraintLayout
ConstraintLayout
Button
Note the unbound error. SinceButton
the isConstraintLayout
inside the , you must set vertical and horizontal constraints to position the Button.
Determine the position of the Button
In this step, you'll add Button
a TextView
vertical constraint from the top of the to the bottom of the . This Button
will position TextView
the below the .
- In Design view, on the top edge
Button
of , press and hold the white circle with a blue border. Drag the pointer, and the arrow will follow the pointer. Release when the pointer reaches the bottom edge of "Hello World"TextView
. This establishes a layout constraint thatButton
will slideTextView
directly below the .
- Take a look at Attributes on the right side of the layout editor .
- In the Constraint Widget , you'll see a new layout constraint set for the bottom
TextView
of ie, Top → BottomOf textView (0dp) . (0dp) means a margin of 0. You'll also run into errors with missing horizontal constraints.
- Adds a horizontal constraint from the left side
Button
of to the left side of the parent .ConstraintLayout
- Then do the same for the right side
Button
,ConstraintLayout
connecting the right edge of to the right edge of . The result should look like this:
Button
When kept selected , the Constraint Widget should look like this. Note that the following two additional constraints are added: Start → StartOf parent (0dp) and End → EndOf parent (0dp) . ThisButton
meansConstraintLayout
horizontally centered within its parent (ie.
- Run the application. The app interface should look like the screenshot below. You can click
Button
, but do nothing yet. Let's keep building!
Change Button Text
You will make some interface changes in the layout editor
Instead of using Button
the label to say "Button", change it to indicate what the button will do: "Roll".
- In the Layout Editor **,
Button
with selected , go to Attributes , change ** text to Roll and press theEnter
(on MacReturn
) key.
- In the Component Tree ,
Button
an orange warning triangle will appear next to it. If you hover the pointer over the triangle, a message is displayed. Android Studio detected a hardcoded string ("Roll") in your app code and suggested using a string resource instead.
Using hard-coded strings means that the application will be difficult to translate to other languages, and it will be difficult to reuse strings in different parts of the application. Fortunately, Android Studio will automatically fix it for you.
- In the Component Tree , click the orange triangle.
A full warning message opens.
- At the bottom of the message, click the Fix button under Suggested Fix . (you may need to scroll down).
- The Extract Resource dialog opens. To extract a string, you need to use the literal "Roll" and create a string resource named
strings.xml
in ( app > res > values > strings.xml ). The defaults are correct, click OK .roll
- Note that in the Attribute s, the text
Button
attribute of the will now show up , representing the resource you just created.@string/roll
In Design view, the Button still shows Roll.
Style the TextView
The "Hello World!" text is small, and the message has nothing to do with your app. In this step, you'll replace the small message "Hello, World!" with a numeric value showing the value of the sieve result, and make the font larger so users can see it.
- In the Design Editor , select
TextView
so that its attributes appear in the Attributes window. - Change the textSize
TextView
of the to 36sp , making it large enough to be easily read by the user. You may have to scroll to find textSize .
TextView
Clear the text property of the . You don't need to display anything inTextView
the .
However, when editing the layout and code for your app, it can be helpful to review some of the text TextView
in . You can do this by TextView
adding text to the , which is only shown in the layout preview and not while the app is running.
- Select in Component Tree
TextView
. - Under Common Attributes , find the text attribute, below which there will be another text attribute with a tool icon. The text property is what is displayed to the user when the app is running. The text attribute with the tool icon is the "tools text" attribute for developers.
- Set the tools text to "1" in
TextView
the (to assume you rolled the dice for a 1). "1" will only be displayed in Android Studio's Design Editor , not when running the app on an actual device or emulator.
Note that because this text is only viewed by app developers, you don't need to make a string resource for it.
- Check out your app in preview. The system will display "1".
- Run your application. Here's what the app looks like when it's running on the emulator. The system does not display "1". The behavior is correct.
Great, you've made your layout changes!
In this way, you've created an app with a Button, but when you tap the Button, the app doesn't do anything. To change that, you need to write Kotlin code to roll the dice and update the screen when the Button is tapped.
Making this change requires a more detailed understanding of how Android apps are built.
4. Introduction to Activity
Activity
Provides a window in which an application can draw its interface. Typically, Activity
the entire screen of a running application is taken up. Every application has one or more activities. The top-level Activity, or first Activity, as it is commonly called MainActivity
, is provided by the project template. For example, when a user scrolls through the list of apps on the device and taps the "Dice Roller" app icon, the Android system launches the app MainActivity
.
In MainActivity
the code , you need to provide Activity
the layout of the and the details of how the user should interact with it.
- In the Birthday Card app, there is a
Activity
to display the birthday message and picture. - In the Dice Roller app, there is a
Activity
to displayTextView
the andButton
layouts you just built.
For more complex applications, multiple screens and multiples may be set up Activity
. Each Activity
has a specific purpose.
For example, in the Photo Gallery app, you can use one Activity
to display a grid of photos, one Activity
to view individual photos, and another Activity
to modify individual photos.
Open the MainActivity.kt file
You'll add code to respond to button taps MainActivity
in the . To do this correctly, you need to have a detailed understanding MainActivity
of the code .
- Navigate to
MainActivity.kt
Files and open the file ( app > java > com.example.diceroller > MainActivity.kt ). You should see the following: If soimport...
, click...
to expand the import.
package com.example.diceroller
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}
You don't need to understand every word of the code above, but you do need a general idea of what it does. The more you work with the Android code, the more familiar you become with it and the better you understand it.
- View the Kotlin code for
MainActivity
the class ,class
identified by the keyword and name.
class MainActivity : AppCompatActivity() {
...
}
- Note that there is no function
MainActivity
in your .main()
Earlier, you learned that every Kotlin program must have main()
a function . Android apps work differently. When you open the app for the first time, the Android system MainActivity
calls onCreate()
the method of the instead of main()
the function .
- Find
onCreate()
the method , which looks like the following code.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
You'll find out in a later article override
(don't worry about it for now). onCreate()
The rest of the method is set up using the code in the import MainActivity
, and setContentView()
sets .
- Note
import
the lines starting .
Android provides a framework of classes to help you write Android apps more easily, but you need to know exactly which classes you're referring to. You can use import
the statement to specify the classes in the framework to use in your code. For example, Button
classes are defined android.widget.Button
in .
Enable automatic import
As you use more classes, remember that adding import
statements will become tedious. Fortunately, Android Studio can help you choose the correct import when you use classes provided by other programs. In this step, you'll configure Android Studio to automatically add imports whenever possible and automatically remove unused imports from your code.
- In Android Studio, if using macOS, go to File > New Project Settings > Preferences for New Project to open the settings. In Windows, go to File > Other Settings > Setting New Project… .
- Expand Other Settings > Auto Import . In the Java and Kotlin section, make sure Add unambiguous imports on the fly and Optimize imports on the fly (for current project) are checked . Note that there are two checkboxes in each section.
The explicit import setting instructs Android Studio to automatically add import statements whenever it can determine which one to use. The optimize imports setting instructs Android Studio to remove any imports that are not used by your code.
- Press OK to save changes and close Setup.
5. Set the Button to be interactive
Now that MainActivity
you know a little more about , you'll modify the app so that taps Button
perform certain actions on the screen.
Show message when Button is clicked
In this step, you will specify that when the Button is clicked, a short message should appear at the bottom of the screen.
setContentView()
Add the following code to the method after callingonCreate()
.findViewById()
Methods are found in layoutsButton
.R.id.button
is the resource IDButton
of the , which is the unique identifier for the Button. Instead of saving the object itself,Button
the code saves a reference to the object in a variable named .rollButton
Button
val rollButton: Button = findViewById(R.id.button)
Note: Android automatically assigns ID numbers to resources in applications. For example, the Roll button has a resource ID, and the string for the button text also has a resource ID. Resource IDs are in the format R.. ; for example R.string.roll . For View IDs,for the id , eg R.id.button .
The code saves a reference to Button
the object rollButton
in a variable named instead of Button
the object itself.
Important Note: When assigning an object to a variable, Kotlin does not copy the entire object every time, but saves a reference to the object. You can think of a reference as a national identification number; the number represents a person, but not the person themselves. When copying a number, the corresponding person will not be copied.
The onCreate() method should now look like this:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val rollButton: Button = findViewById(R.id.button)
}
- Verify that Android Studio automatically
Button
addedimport
the statement for . Notice that there are now 3 import statements, and the third statement was added automatically.
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
Note: Failure to enable auto-import
Button
will be highlighted in red. You can manually add the correct import action by placing the text cursorButton
inside and pressingAlt+Enter
(on a Mac, pressOption+Enter
).
Next, you need to Button
associate the so that Button
it executes when the is tapped. A click listener is code that performs an action when a tap or click occurs. The click listener here is used to monitor the user's Button
click operation.
- Use
rollButton
the object , and callsetOnClickListener()
the method to set the click listener for it. In fact, you would use curly braces after the method name, not parentheses after the method name. This is a special syntax for declaring Lambdas , more details in a future article.
What you need to notice now is that inside the braces, there is a description of what should happen when the button is tapped. You can have your app display a message box with a brief message about what to do next.
rollButton.setOnClickListener {
}
During typing, Android Studio may display several suggestions. For this example, select the setOnClickListener {…} option.
In curly brackets, you can describe what the button should do when it is tapped. Now you can tell your app to display Toast
, a short message to the user.
- Create a containing literal
Toast.makeText()
by calling ."Dice Rolled!"
Toast
val toast = Toast.makeText(this, "Dice Rolled!", Toast.LENGTH_SHORT)
- Then
show()
, tellToast
the to display itself by calling the method.
toast.show()
The updated MainActivity
class looks like this; package
and import
statements are still at the top of the file:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val rollButton: Button = findViewById(R.id.button)
rollButton.setOnClickListener {
val toast = Toast.makeText(this, "Dice Rolled!", Toast.LENGTH_SHORT)
toast.show()
}
}
}
You can combine the two lines in the click listener into one without using a variable. This pattern is a common pattern that you'll find in other code as well.
Toast.makeText(this, "Dice Rolled!", Toast.LENGTH_SHORT).show()
- Run the app and hit the Roll button. A message box message will pop up at the bottom of the screen and disappear after a short while.
marvelous! After clicking the button, the message will pop up! This is your first time writing Kotlin code for Android!
Update TextView when Button is clicked
Instead of displaying a temporary message you need to write code to update the on-screen when the user taps the Roll button.TextView
Toast
- Go back to
activity_main.xml
( app > res > layout > activity_main.xml ) - click
TextView
.
- Note that the id is textView .
- Open
MainActivity.kt
( app > java > com.example.diceroller > MainActivity.kt ) - Remove the lines
Toast
of .
rollButton.setOnClickListener {
}
- Create a new variable
resultTextView
called to storeTextView
. - Use
findViewById()
to look up the ID of the textView in the layouttextView
and store a reference to it.
val resultTextView: TextView = findViewById(R.id.textView)
resultTextView
Set the text on to a quoted "6".
resultTextView.text = "6"
This is similar to setting text in Attributes , but it's now in code, so the text must be in double quotes. Setting this explicitly means that 6 is currently always displayed. You'll add code to roll the dice and display different values in the next task.TextView
MainActivity
The content of the class should look like this:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val rollButton: Button = findViewById(R.id.button)
rollButton.setOnClickListener {
val resultTextView: TextView = findViewById(R.id.textView)
resultTextView.text = "6"
}
}
}
- Run the application. Click the button. It should update the TextView to "6".
6. Add dice rolling logic
The only action missing is actually rolling the dice. You can reuse the Dice class from the previous article, which is responsible for performing the logic for rolling the dice.
Add the Dice class
- After the last curly brace in
MainActivity
the class , useroll()
the method to createDice
the class .
class Dice(val numSides: Int) {
fun roll(): Int {
return (1..numSides).random()
}
}
- Note that Android Studio may underline
numSides
with a gray squiggly line. (It may take a while to appear). - Hover the pointer
numSides
over and a pop-up window displays Property 'numSides' could be private .
numSides
Marking as private
will allow access to numSides only in Dice
the class . Since the only code numSides
using is Dice
in the class, you can set this parameter to private
for Dice
the class. In the next unit, you'll learn about private
and public
variables.
- Go ahead and click Make 'numSides' 'private', as suggested by Android Studio.
Create the rollDice() method
Now that you've added Dice
the class , you'll update MainActivity
to use it. To better organize your code, put all the logic about rolling the dice in one function.
- Replace the code in the click listener that sets the text to "6" by
rollDice()
calling .
rollButton.setOnClickListener {
rollDice()
}
- Since it is not defined
rollDice()
, Android Studio flags the error and displays it in red fontrollDice()
. - If you hover the pointer
rollDice()
over , Android Studio displays the problem and some possible solutions.
- Click More actions… and a menu will appear. Android Studio helps you get more done!
Tip: If you find it difficult to hover over the pointer and click More actions... , you can click and press (on a Mac ) to open the menu.
rollDice()
Alt+Enter
Option+Enter
- Select Create function 'rollDice' . Android Studio creates empty definitions for functions
MainActivity
inside .
private fun rollDice() {
TODO("Not yet implemented")
}
Create a new Dice object instance
In this step, you'll use rollDice()
the method to create and roll a dice, then TextView
display the result in a .
rollDice()
In , removeTODO()
the call to .- Add code to create a 6-sided die.
val dice = Dice(6)
- Roll the dice by calling
roll()
the method and save the resultdiceRoll
in a variable named .
val diceRoll = dice.roll()
findViewById()
Find by callingTextView
.
val resultTextView: TextView = findViewById(R.id.textView)
The variable diceRoll
is a number, but TextView
uses literals. You can use the method diceRoll
on toString()
to convert it to a string.
diceRoll
Converts to a string and updatesresultTextView
the text of the with that string.
resultTextView.text = diceRoll.toString()
rollDice()
The method looks like this:
private fun rollDice() {
val dice = Dice(6)
val diceRoll = dice.roll()
val resultTextView: TextView = findViewById(R.id.textView)
resultTextView.text = diceRoll.toString()
}
- Run your application. The dice result should be changed to something other than 6! Since it is a random number from 1 to 6, the value 6 will sometimes appear.
Great, you are awesome!
7. Adopt good coding practices
Once you've tweaked the pieces here and got your app working, it's perfectly normal for your code to look a bit messy. However, before you leave your code, you should perform some simple cleanup tasks. This way, the app will stay in good shape and will be easier to maintain in the future.
These are the habits of professional Android developers when writing code.
Android Style Guide
When working with a team, it's a good idea for team members to write code in a similar fashion to maintain consistency across code. Because of this, Android provides a set of style guides on how to write Android code, including naming conventions, formatting, and other good practices to follow. Follow these guidelines when writing Android code: Kotlin Style Guide for Android Developers .
You can follow a style guide in several ways.
clean up code
compressed code
You can condense your code into a few shorter lines of code, making your code more concise. For example, the following code sets a click listener Button
on .
rollButton.setOnClickListener {
rollDice()
}
Because the click listener specification is only 1 line, you can compress rollDice()
the method call and curly braces into one line. Its appearance is as follows. Use one line instead of three!
rollButton.setOnClickListener {
rollDice() }
reformat the code
Now you'll reformat the code to make sure it follows the recommended Android code formatting guidelines.
- In
MainActivity.kt
the class , use the keyboard shortcut on WindowsControl+A
(or on MacCommand+A
) to select all text in the file. Alternatively, you can go to the menu ( Edit > Select All ) in Android Studio to do it. - With all the text in the file selected, go to Code > Reformat Code in the Android Studio menu , or use the keyboard shortcut
Ctrl+Alt+L
(on a MacCommand+Option+L
).
This will update the formatting of the code, including whitespace, indentation, etc. You probably won't see any changes, which is best. Then your code should be properly formatted!
Add code comments
Add some comments to your code to describe what the code you wrote does. As your code grows in complexity, you also have to remember why you wrote the code to perform the function in question. If you later return to that code to make changes, it might still be perfectly clear what the code does, but you might not remember why you wrote it that way in the first place.
Typically add annotations to every class ( MainActivity
and Dice
is the only class in your app) and every method you write. Use the /**
and **/
to tell the system that this is not code. These lines are ignored when executing your code.
An example of a comment on a class:
/**
* 这个活动允许用户掷骰子并在屏幕上查看结果。
*/
class MainActivity : AppCompatActivity() {
Example of a comment on a method:
/**
* 用掷骰子的结果更新屏幕。
*/
private fun rollDice() {
Within methods, feel free to add comments if you wish to help readers understand the code. Note that you can use //
the symbol . //
Everything after the symbol on a line is considered a comment.
Example of 2 comments in a method:
private fun rollDice() {
// 创建一个有6个面的新的 骰子 对象,然后滚动它
val dice = Dice(6)
val diceRoll = dice.roll()
// 用骰子更新屏幕
val resultTextView: TextView = findViewById(R.id.textView)
resultTextView.text = diceRoll.toString()
}
- Go ahead and take a moment to comment your code.
- After making comments and formatting changes, it's a good idea to run the app again to make sure it works as expected.
Review the solution code to learn how to add comments to the code.
Eight, solution code
The solution code for this article is in the projects and modules shown below.
Solution code URL: https://github.com/google-developer-training/android-basics-kotlin-create-dice-roller-with-button-app-solution
To get the code for this article and open it in Android Studio, do the following.
get code
- Click on the URL provided. The project's GitHub page opens in your browser.
- On the project's GitHub page, click the Code button to open a dialog.
- In the dialog, click the Download ZIP button to save the project to your computer. Wait for the download to complete.
- Locate the file on your computer (probably in the Downloads folder).
- Double-click the ZIP file to extract it. A new folder will be created containing the project files.
Open the project in Android Studio
- Start Android Studio.
- In the Welcome to Android Studio window, click Open an existing Android Studio project .
Note: If Android Studio is already open, select the File > New > Import Project menu option.
- In the Import Project dialog, go to where the unzipped project folder is located (probably in the Downloads folder).
- Double-click the project folder.
- Wait for Android Studio to open the project.
- Click the Run button to build and run the application. Please make sure the app is working properly.
- Browse the project file in the Project tool window to see how your app will be implemented.
Nine. Summary
- Added in the Android app using the layout editor
Button
. - Modify
MainActivity.kt
the class to add interactive behavior to your application. Toast
The message pops up as a temporary solution to verify that you are doing it correctly.- Use
setOnClickListener()
toButton
set a click listener for to add behaviorButton
when . - While your app is running, you can update the screen by calling methods on the
TextView
, or other UI elements in your layout .Button
- Comment your code to help other readers understand your methods.
- Reformatted code and cleaned up code.
10. Learn more
" Basics of Android Development Using Kotlin " Related VocabularyButton
kindToast
kindTextView
kind- Kotlin Style Guide for Android Developers
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:
- Add another dice to the app. Clicking the Roll button will roll 2 dice. The results are displayed on the screen in two different TextViews.
Check your works:
The created app should run without errors and display two dice in the app.