Build Your First App

1. Dice Roller App

App Manifest Overview

Activity




setContentView

Linear Layout Documentation

In this exercise, you will add a button to your app the same way we have done in the video.

1. Copy the layout XML code below if you haven’t done so already:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        android:text="1" />

</LinearLayout>

2. Add another XML tag for the button:

Make sure you set the text to “Roll” by extracting the string to resources and aligning the button horizontally towards the center of the screen.

<Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="@string/roll" />

3. Position all views in LinearLayout:

To do so, set the orientation of the LinearLayout to vertical and use layout_gravity to align the elements so they are centered as expected.

android:layout_gravity="center_vertical"
android:orientation="vertical"

If you want to start at this step, you can download this exercise code from: Step.01-Exercise-Adding-the-button.

You will find plenty of //TODO comments to help you complete this exercise, and if you get stuck, go back and watch the video again.

Once you’re done, you can check your solution against the solution we’ve provided here Step.01-Solution-Adding-the-button or using this git diff.



A note about the view binding feature (Android Studio 3.6+)
Since Developing Android Apps with Kotlin has launched, a new feature, view binding, has been introduced and is available in Android Studio 3.6 and higher. We don't use view binding because it came out after the course, but it's a feature to be aware of.

View binding replaces findViewById. View binding generates a binding object for each XML layout. You use this binding object to reference views, using their resource ids as the name:

// Creating a binding object for the main_activity.xml layout
binding = ActivityMainBinding.inflate(layoutInflater) 

// Referencing a view with the ID roll_button
binding.rollButton 

View binding has the following benefits over findViewById:

  • Type safety - findViewById requires you to specify the type of view you expect to be returned. For example, if you accidentally specify that you expect an ImageButton to be returned when the actual type is a Button, you'll get a ClassCastException. View binding protects you from this type of error because the view is a correctly typed property of the binding.
  • Null safety - findViewById expects an integer parameter, which is meant to be the resource ID of a view. It is possible, though, to pass in any integer as a parameter, including unrelated integers and invalid view ids. If you supply an integer that doesn't match a view resource id in the layout, findViewById returns null and can cause a NullPointerException. View binding is null safe because you reference view objects directly and don't look them up by integer IDs.

To learn more about how to use view binding in your app, check out the View Binding documentation and the Accessing Views portion of What's new in Architecture Components (Google I/O'19).



Now it’s your turn to complete this exercise yourself.

In this exercise, you will use findViewById to get a reference to the button.

1. Set button’s id in the activity_main.xml layout file:

android:id="@+id/roll_button"

2. Use findViewById to get a reference to the button and assign it to an immutable variable called rollButton:

val rollButton: Button = findViewById(R.id.roll_button)

3. (Optional) Dynamically modify the Button view:

Set the button text to "Roll Button"

rollButton.text = "Let's Roll"



In this exercise, you will make your app show a Toast message every time the button is clicked.

1. Make sure that you've completed the steps to findViewById:

You'll need to findViewById for the button, as described in the last video.

3. Set the OnClickListener for the button:

rollButton.setOnClickListener {

}

4. Make the Toast:

This code will make the rollButton show a Toast message.

rollButton.setOnClickListener {
    Toast.makeText(this, "button clicked", Toast.LENGTH_SHORT).show()
}

If you want to start at this step, you can download this exercise code here: Step.02-Exercise-OnClickListener.

You will find plenty of //TODO comments to help you complete this exercise, and if you get stuck, go back and watch the video again.

Once you’re done, you can check your solution against the solution we’ve provided here Step.02-Solution-OnClickListener or using this git diff



In this exercise, you will make your app show a random number in the result_text TextView.

1. Assign an id to TextView in the layout:

android:id="@+id/result_text"

2. Remove the Toast and create a method called rollDice:

You can do this by adding the following:

rollButton.setOnClickListener {
    rollDice()
}

And then using the keyboard shortcut, you can generate the method in Android Studio:

  • Windows/Linux: Alt + Enter
  • Mac: Option + Enter

3. Write have the rollDice method to get a random number between 1 and 6:

val randomInt = Random().nextInt(6) + 1

4. Use findViewById to get a reference to the TextView and assign it to an immutable variable called resultText:

val resultText: TextView = findViewById(R.id.result_text)

5. Finally, set the random value that you got above as the text of the TextView:

resultText.text = randomInt.toString()

If you want to start at this step, you can download this exercise code here: Step.03-Exercise-Rolling-the-dice.

You will find plenty of //TODO comments to help you complete this exercise, and if you get stuck, go back and watch the video again.

Once you’re done, you can check your solution against the solution we’ve provided here Step.03-Solution-Rolling-the-dice or using this git diff



In this exercise, you will replace the TextView with an ImageView that will show the right drawable based on the random number.

1. Add the dice images to the drawable folder

Add the Dice images file as explained in the previous video.

2. Replace TextView with ImageView and assign empty_dice drawable to it:

<ImageView
        android:id="@+id/dice_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:src="@drawable/empty_dice" />

3. Replace reference to the TextView with the ImageView:

val diceImage: ImageView = findViewById(R.id.dice_image)

4. Choose the right drawable resource based on the value of randomInt:

val drawableResource = when (randomInt) {
            1 -> R.drawable.dice_1
            2 -> R.drawable.dice_2
            3 -> R.drawable.dice_3
            4 -> R.drawable.dice_4
            5 -> R.drawable.dice_5
            else -> R.drawable.dice_6
        }

5. Finally, assign the drawableResource from above to diceImage:

diceImage.setImageResource(drawableResource)

If you want to start at this step, you can download this exercise code here: Step.04-Exercise-Adding-the-ImageView.

You will find plenty of //TODO comments to help you complete this exercise, and if you get stuck, go back and watch the video again.

Once you’re done, you can check your solution against the solution we’ve provided here Step.04-Solution-Adding-the-ImageView or using this git diff.


Here is additional information on the topic of late initialization if you are curious: late-initialized-properties-and-variables.

Now it’s your turn to complete this exercise yourself.

1. Use lateinit to extract the image view variable:

lateinit var diceImage: ImageView

2. Initialize the image view variable:

diceImage = findViewById(R.id.dice_image)

If you want to start at this step, you can download this exercise code here: Step.05-Exercise-Finding-Views-Efficiently.

You will find plenty of //TODO comments to help you complete this exercise, and if you get stuck, go back and watch the video again.

Once you’re done, you can check your solution against the solution we’ve provided here Step.05-Solution-Finding-Views-Efficiently or using this git diff.


For more about namespaces, you can read about XML namespaces here

To learn more about the tools name space in particular, check out the documentation







The full explanation of generated Gradle files can be found here.





Gradle Building

If you're trying to decide what versions to support, you can check out:

  • The "help me choose" dialog, which is shown when you're setting up Andorid Studio
  • The release notes for each version
  • Platform version dashboard

Revise it again.

Now it’s your turn to complete this exercise.

1. Enable the use of support library for vector drawables in build.gradle file (app level):

vectorDrawables.useSupportLibrary = true

2. Use app:srcCompat in the image tag in the layout file:

app:srcCompat="@drawable/empty_dice"

3. You’ll also need to add the namespace to the root of the layout:

xmlns:app="http://schemas.android.com/apk/res-auto"

If you want to start at this step, you can download this exercise code here: Step.06-Exercise-Use-Vector-Drawable-Compat.

You will find plenty of //TODO comments to help you complete this exercise, and if you get stuck, go back and watch the video again.

Once you’re done, you can check your solution against the solution we’ve provided here Step.06-Solution-Use-Vector-Drawable-Compat or using this git diff.









0 Comments

Brand creation, trend analysis & style consulting

Lorem Ipsum has been the industry's standard dummy text ever since. Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since.