【Add pictures to Dice Roller app】

Previous: 【Add Conditional Behavior in Kotlin】

1. Preparation

In this article, you'll add dice images to the existing Dice Roller Android application. Be sure to complete the previous article on building the basics of a Dice Roller application first.

Instead of displaying the resulting value of a dice roll in TextViewthe displays an image of the dice corresponding to the number rolled. This will make your app more intuitive and enhance the user experience.

insert image description here

We will provide you with a download link of the dice image, which you can add to your application as a resource. In order to code the dice image to use, you need to use whenthe statement .

prerequisite

  • Completed the "Creating an Interactive Dice Roller Application" article.
  • Ability to write control flow statements ( if / else, whenstatement).
  • Ability to update application interface (modify MainActivity.ktfile .
  • Ability to Button.add .
  • Ability to add image resources to Android applications.

Learning Content

  • How to update while the app is running ImageView.
  • How (using whenstatements ) to customize app behavior based on different conditions.

what you will build

  • ButtonDice Roller Android app with , which can be used to roll the dice and update the picture on the screen.

required tools

  • A computer with Android Studio installed.
  • Internet connection in order to download dice pictures.

2. Update the layout of the application

In this task, you'll TextViewreplace with one that displays a picture of the result of the dice roll ImageView.

Open the Dice Roller app

  1. Open the Dice Roller application created in the previous article in Android Studio and run the application. You can use solution codes or codes that you create.

The application should look like this.

insert image description here

  1. Open activity_main.xml( app > res > layout > activity_main.xml ). The Layout Editor opens .

removeTextView

  1. In the layout editor , select the Component TreeTextView .

insert image description here

Tip: As you add more UI components and add and remove constraints, you may sometimes find that the overlap Vieweach other , making it difficult to select the view below. In this case you can choose in Component TreeView .

  1. Right-click and select Delete , or press Deletethe key .
  2. Please ignore the warning Buttonon . You'll fix that in the next steps.

Add ImageView to layout

  1. Drag ImageViewfrom the Palette onto the Design view and place it Buttonabove the .

insert image description here

  1. In the Pick a Resource dialog, select the avatars in Sample data . This temporary image will be used until the dice image is added in the next task.

insert image description here

  1. Click OK . The App's Design view should look like this.

insert image description here

  1. In Component Tree you will find two errors. ButtonNot vertically constrained, ImageViewneither vertically nor horizontally constrained.

insert image description here

Buttonis not vertically constrained because you removed what was above it TextView. Now you need ImageViewto Buttonplace and below it.

Determine the position of ImageView and Button

No Buttonmatter where it is, you need to ImageViewcenter it vertically on the screen.

  1. ImageViewAdd horizontal constraints for . ImageViewJoins the left edge of the to ConstraintLayoutthe left edge of the parent .
  2. ImageViewJoins the right side of the with the parent's right edge. This ImageViewwill center horizontally within the parent.

insert image description here

  1. To ImageViewadd a vertical constraint, ImageViewconnect the top of the to the top of the parent. ImageViewwill slide up to the top ConstraintLayoutof the .

insert image description here

  1. To Buttonadd a vertical constraint, connect Buttonthe top of ImageViewto the bottom of . Buttonwill slide ImageViewup the .

insert image description here

  1. Now, select again ImageView, and add a vertical ImageViewconstraint connecting the bottom of the to the bottom of the parent. This ImageViewwill ConstraintLayoutcenter vertically within the .

All warnings about constraints will now disappear.

After doing all of the above, the Design view should look like this, ImageViewcentered and Buttondirectly below it.

insert image description here

You may see a warning on in the Component Tree prompting you to add a content description to the . Don't worry about this warning for now, because later in the article you'll explain what to . You will make this change in Kotlin code.ImageViewImageViewImageView

3. Add dice pictures

In this task, you will download some dice images and add them to the application.

download dice image

  1. Open this URL to download the ZIP file containing the dice picture to your computer. Wait for the download to complete.
  2. Locate the file on your computer (probably in the Downloads folder).
  3. Double-click the ZIP file to extract it. This will create a new dice_imagesfolder containing 6 dice image files showing dice values ​​from 1 to 6.

insert image description here

Add a dice image to your app

  1. In Android Studio, click View > Tool Windows > Resource Manager in the menu , or click the Resource Manager tab on the left side of the Project window .
  2. Click the + in the upper left corner in the Resource Manager , then select Import Drawables . A file browser will open.

insert image description here

  1. Find and select the 6 dice image files above. You can select the first dice image first, then select other images while holding down Shiftthe key .
  2. Click Open .
  3. Click Next and then Import to confirm that you want to import these 6 resources.

insert image description here

insert image description here

  1. If the file was imported successfully, the 6 images will be displayed in the app's Resource Manager ( app>res>drawable ).

insert image description here

Great! You'll use these images in your app in the next task.

important hint! - You will be able to view these images by their resource IDs in Kotlin code:

  • R.drawable.dice_1
  • R.drawable.dice_2
  • R.drawable.dice_3
  • R.drawable.dice_4
  • R.drawable.dice_5
  • R.drawable.dice_6

4. Use dice pictures

Replace example avatar

  1. In the Design Editor , select ImageView.
  2. In the Attributes of the Declared Attributes section , find the tool srcCompat attribute set to the avatar image .

Note that the tool srcCompat attribute only uses the provided image in Android Studio's Design view. The image is only shown to developers when you build the app, not when you actually run the app on an emulator or device.

  1. Click on the small preview image of the avatar. A dialog box opens allowing you to select a new resource to use for ImageViewthis .

insert image description here

  1. dice_1Select Drawable and click OK .

Wow! ImageViewtakes up the entire screen.

insert image description here

Next, you'll ImageViewadjust the width and height of the to make sure it doesn't obscure it Button.

  1. In the Attributes window under the Constraints Widget , find the layout_width and layout_height attributes. They are currently set to wrap_content , which means the height and width of the will match the content (source image) within it.ImageView
  2. ImageViewSet a fixed width of 160dp and a fixed height of 200dp for . Press Enter .

ImageViewNow the size is much smaller.

insert image description here

You may find that the Button is too close to the image.

  1. Set the button's top margin to 16dp in the Constraint Widget .

insert image description here

The app looks even better now that the Design view has been updated!

insert image description here

Note: Use density-independent pixels (dp) as units for these dimensions so that images scale properly on devices with different pixel resolutions.

Change dice image when button is clicked

While the layout has been corrected, MainActivitythe class to use dice images.

MainActivity.ktThere is currently an application error in the file. If you try to run the app, you'll see the following build errors:

insert image description here

This is because your code is still referencing the one you have removed from the layout TextView.

  1. Open MainActivity.kt( app > java > com.example.diceroller > MainActivity.kt )

The code references it R.id.textView, but Android Studio doesn't recognize it.

insert image description here

  1. In rollDice()the method , select any TextViewcode that references and delete it.
// Update the TextView with the dice roll
val resultTextView: TextView = findViewById(R.id.textView)
resultTextView.text = dice.roll().toString()
  1. Still rollDice()in , create a ImageViewnew variable of type diceImage. Set it to ImageViewbe the same . Use findViewById()the method , passing in ImageViewthe resource of ID R.id.imageViewas an input parameter.
val diceImage: ImageView = findViewById(R.id.imageView)

If you want to know how to determine ImageViewthe exact resource ID of the , look at Attributesthe top of the window id.

insert image description here

When referencing this resource ID in Kotlin code, make sure to type it exactly (lowercase i, uppercase V, no spaces). Otherwise, Android Studio will display an error.

  1. Add the following line of code to test that the button updates correctly when clicked ImageView. The dice are not always rolled with "2", we just use dice_2the picture for testing.
diceImage.setImageResource(R.drawable.dice_2)

This code ImageViewcalls setImageResource()the method on the , passing dice_2the image 's resource ID. This will update the on-screen ImageViewto display dice_2the picture.

The rollDice() method should now look like this:

private fun rollDice() {
    
    
    val dice = Dice(6)
    val diceRoll = dice.roll()
    val diceImage: ImageView = findViewById(R.id.imageView)
    diceImage.setImageResource(R.drawable.dice_2)
}
  1. Run the app to verify that it works without errors. The app should show a blank screen (only the Roll button) when launching the app.

insert image description here

When the button is tapped, a picture of a dice showing a value of 2 appears. Very good! !

insert image description here

Now you can change pictures with button taps! You are getting closer to your goal!

5. Display the correct dice picture according to the result of the dice roll

Obviously, the dice result is not always 2. Use the control flow logic you learned in Adding Conditional Behaviors for Different Dice Rolls to display the appropriate dice image on the screen based on the random outcome of the dice roll.

Before you start typing code, think conceptually about how your app should behave by writing some pseudocode to describe what should happen. For example:

If the user rolls a 1, the dice_1 picture is displayed.

If the user rolls a 2, the dice_2 picture is displayed.

etc…

Note: Pseudocode is an informal illustration of how some code works. It uses some computer language elements, for example if / else, but describes it in a way that humans can understand. Pseudocode is useful if you want to plan the correct approach before all the details are fixed.

In Kotlin, the above pseudocode can be written using if / elsethe statement .

if (diceRoll == 1) {
    
    
   diceImage.setImageResource(R.drawable.dice_1)
} else if (diceRoll == 2) {
    
    
   diceImage.setImageResource(R.drawable.dice_2)
}
 ...

But writing for each case if / elsewould be a lot of repetitive work. The same logic can be expressed simply using whenthe statement . It's more concise (uses less code)! Please use this method in your application.

when (diceRoll) {
    
    
   1 -> diceImage.setImageResource(R.drawable.dice_1)
   2 -> diceImage.setImageResource(R.drawable.dice_2)
   ...

Update rollDice() method

  1. In rollDice()the method , remove dice_2the line of code that sets the image resource ID to an image each time.
diceImage.setImageResource(R.drawable.dice_2)
  1. Replace it with whena statement that ImageViewupdates based on the value diceRoll.
  when (diceRoll) {
    
    
       1 -> diceImage.setImageResource(R.drawable.dice_1)
       2 -> diceImage.setImageResource(R.drawable.dice_2)
       3 -> diceImage.setImageResource(R.drawable.dice_3)
       4 -> diceImage.setImageResource(R.drawable.dice_4)
       5 -> diceImage.setImageResource(R.drawable.dice_5)
       6 -> diceImage.setImageResource(R.drawable.dice_6)
   }

After making the changes, rollDice()the method should look like this.

private fun rollDice() {
    
    
   val dice = Dice(6)
   val diceRoll = dice.roll()

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

   when (diceRoll) {
    
    
       1 -> diceImage.setImageResource(R.drawable.dice_1)
       2 -> diceImage.setImageResource(R.drawable.dice_2)
       3 -> diceImage.setImageResource(R.drawable.dice_3)
       4 -> diceImage.setImageResource(R.drawable.dice_4)
       5 -> diceImage.setImageResource(R.drawable.dice_5)
       6 -> diceImage.setImageResource(R.drawable.dice_6)
   }
}
  1. Run the application. Clicking the Roll button will change the dice picture to a value other than 2. Success!

insert image description here

optimize your code

If you want to write more concise code, you can make the following code changes. This won't have any noticeable impact on your app's users, but will shorten your code and reduce duplication.

You may have noticed that there are 6 calls to diceImage.setImageResource() in the when statement.

when (diceRoll) {
    
    
    1 -> diceImage.setImageResource(R.drawable.dice_1)
    2 -> diceImage.setImageResource(R.drawable.dice_2)
    3 -> diceImage.setImageResource(R.drawable.dice_3)
    4 -> diceImage.setImageResource(R.drawable.dice_4)
    5 -> diceImage.setImageResource(R.drawable.dice_5)
    6 -> diceImage.setImageResource(R.drawable.dice_6)
}

The only thing that changes between each case is the resource ID used. This means you can create a variable that stores the ID of the resource you want to use. Then, just call diceImage.setImageResource()once and pass the correct resource ID.

  1. Replace the above code with the following code.
val drawableResource = when (diceRoll) {
    
    
   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
   6 -> R.drawable.dice_6
}

diceImage.setImageResource(drawableResource)

The new concept used here is that whenexpressions can actually return a value. With this new snippet, whenthe expression returns the correct resource ID, which is stored in drawableResourcethe variable . You can then use this variable to update the displayed image resource.

  1. Note that whenit is now underlined in red. If you hover your pointer over it, you'll see an error message: 'when' expression must be exhaustive, add necessary 'else' branch .

The reason for the error is that the value of whenthe expression is assigned to drawableResource, so whenmust cover all cases, it must handle all possible cases, so even if you change to a 12-sided die, the value will always be returned. Android Studio suggests adding a elsebranch . You 6can elsefix this by changing the case of to . Cases from 1to 5are unchanged, but all other cases 6including are elsehandled by .

val drawableResource = when (diceRoll) {
    
    
   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
}

diceImage.setImageResource(drawableResource)
  1. Run the app to make sure it's still working. Be sure to test enough to make sure you see all the numbers 1 through 6 with the dice pictures.

Set an appropriate content description on the ImageView

Now that you've replaced the number thrown with an image, the screen reader can no longer tell which number was thrown. To fix this, after updating the image resource, update the content description ImageViewof the . The content description should be the text description displayed ImageViewin so that screen readers can describe it.

diceImage.contentDescription = diceRoll.toString()

Screen readers can read this caption, so if you see a picture of a dice rolling a "6" on the screen, the screen reader can read the caption for "6."

Note: In general, content descriptions should use string resources that can be translated into other languages, which we will cover in detail in later lessons.

6. Adopt standardized coding practices

Create a more usable startup experience

When the user opens the app for the first time, the app is empty (only the Roll button is displayed), which seems odd. Users may not know what to expect, so Activitywhen , change the UI to display random dice. This way the user is more likely to know that tapping Rollthe button rolls the dice.

override fun onCreate(savedInstanceState: Bundle?) {
    
    
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val rollButton: Button = findViewById(R.id.button)
    rollButton.setOnClickListener {
    
     rollDice() }

    // Do a dice roll when the app starts
    rollDice()
}

insert image description here

Add code comments

Add some comments to your code to describe what the code you wrote does.

After making all these changes, your rollDice()method might look like this.

/**
* 掷骰子并用结果更新屏幕。
*/
private fun rollDice() {
    
    
    // 创建一个新的骰子对象,有6个面,然后掷骰子
    val dice = Dice(6)
    val diceRoll = dice.roll()

    // 在布局中查找 ImageView
    val diceImage: ImageView = findViewById(R.id.imageView)

    // 根据掷骰子决定使用哪个可绘制资源 ID
    val drawableResource = when (diceRoll) {
    
    
        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
    }

    // 使用正确的可绘制资源 ID 更新 ImageView
    diceImage.setImageResource(drawableResource)

    // 更新内容描述
    diceImage.contentDescription = diceRoll.toString()
}

For the complete MainActivity.ktfile , see the solution code on GitHub linked in the next step.

Congratulations on completing the creation of your Dice Roller application! Now you can play this game with your friends for your next game night!

Seven, 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-dice-roller-with-images-app-solution

To get the code for this article and open it in Android Studio, do the following.

get code

  1. Click on the URL provided. At this point, the project's GitHub page opens in your browser.
  2. On the project's GitHub page, click the Code button to open a dialog.

insert image description here

  1. In the dialog, click the Download ZIP button to save the project to your computer. Wait for the download to complete.
  2. Locate the file on your computer (probably in the Downloads folder).
  3. Double-click the ZIP file to extract it. A new folder will be created containing the project files.

Open the project in Android Studio

  1. Start Android Studio.
  2. In the Welcome to Android Studio window, click Open an existing Android Studio project .

insert image description here

Note: If Android Studio is already open, select the File > New > Import Project menu option.

insert image description here

  1. In the Import Project dialog, go to where the unzipped project folder is located (probably in the Downloads folder).
  2. Double-click the project folder.
  3. Wait for Android Studio to open the project.
  4. Click the Run button to build and run the application. Make sure the app builds as expected.
  5. Browse the project file in the Project tool window to see how your app is set up.

8. Summary

  • Use setImageResource()to change the picture displayed in the ImageView
  • Use control flow statements such as if / elseexpression or whenexpression to handle different situations in your application, for example, to display different images in different situations.

9. Learn more

10. Practice by yourself

Note: Practice as needed. You can take this opportunity to practice what you have learned in this article.

Please do the following exercises:

  1. Add another dice to the application so that a Roll button provides 2 dice rolls. How many do you need in your layout ImageViews? How does this affect MainActivity.ktthe code ?

Check your works:

The created app should run without errors and display two dice.

Next: [Classes and Inheritance in Kotlin]

Guess you like

Origin blog.csdn.net/Jasonhso/article/details/125994017