MVVM on Android

Sep 1 2022 · Kotlin 1.6, Android 12, Android Studio Chipmunk | 2021.2.1 Patch 1

Part 1: MVVM on Android

03. Build the Model

Episode complete

Play next episode

Next
About this episode
Leave a rating/review
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 02. Understand MVVM Next episode: 04. Model the Repository

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Notes: 03. Build the Model

The parameters of the Creature constructor should be var to prevent the “Cannot find setter for field error.”

Transcript: 03. Build the Model

I have the starter project for the course open up here in Android Studio 3.1.4.

The starter project has three packages: app, model, and view.

The starter code is there to give us a head start on building out the Creaturemon app using MVVM. The app package has an Application subclass for the app, and a file with extension functions for some Kotlin classes.

The view package has Activity, Adapter, and other classes that make up the app UI. We’ll talk about the View classes in a later video.

In this video, we’ll build out the classes in the model package. The starter project includes some code for persisting to a Room database, which we’ll also do in a later video.

There are some classes that we’ll use for creature attributes, and some empty classes that we’ll start filling out in this video.

I’ll build and run the starter app now to get a sense of what we want the app to look like. The first screen will later be used to show the list of creatures that we’ve created. There’s a menu option we’ll use later use to clear all creatures.

Hitting the floating action button, we see the Add Creature screen, which is where we’ll work for most of the course. You see we can tap near the top of the screen to choose an avatar for the creature.

We can assign a name to the creature, as well as intelligence, strength, and endurance attributes. There’s a spot at the bottom to show the creature HitPoints value, based on the chosen attributes. And there’s a button we’ll use to save the new creature.

We’re going to build up the model classes we need for our Creature data. The main class is Creature, which has a set of CreatureAttributes and some other properties for each creature.

Back in Android Studio now, open up the CreatureAttributes file. This is a simple data class with an Int value for each of the three Creature attributes. Next, open the Creature file to see the empty Creature class in the starter project.

Let’s convert this model class to a data class, and add properties for the Creature attributes, hitPoints, name, and also an Int for the avatar drawable value.

data class Creature(
    val attributes: CreatureAttributes = CreatureAttributes(),
    val hitPoints: Int = 0,
    val name: String,
    val drawable: Int = 0
)

We’re also going to need a class in our Model to generate a creature based on the values input by the user on the Add Creature screen.

In particular, we need to calculate the hitpoints value for a creature based on this formula. Hitpoints is equal to 5 times the intelligence attribute, plus 3 times the strength attribute, plus 4 times the endurance attribute. The Creaturemon game favors intelligence over all else.

For the CreatureGenerator, we’ll use Test-Driven Development or TDD and write our test first for the class. If you’ve not done TDD before, just know that TDD is a test-first approach we’re you peform a Red-Green-Refactor cycle.

Red means you first write a failing test, and then write the code that makes the test Green by passing. You follow up with refactoring to make the code you’ve added as clean as possible.

In the test package, create a new package named model. Now add a new Kotlin file to the package named CreatureGeneratorTest.

class CreatureGeneratorTest {

}

Create the test class and add a CreatureGenerator property to it. CreatureGenerator does not exist yet, so we’ll see some compiler errors.

   private lateinit var creatureGenerator: CreatureGenerator

We’ll initialize creatureGenerator in a setup() method tagged with the @Before JUnit annotation:

   @Before
  fun setup() {
    creatureGenerator = CreatureGenerator()
  }

Let’s now go into the model package in the app and create the CreatureGenerator class to clear the compiler error.

class CreatureGenerator

Back in the test class, add the test for the hit point calculation. We first arrange the expectedCreature from the generator.

   @Test
  fun testGenerateHitPoints() {
    val attributes = CreatureAttributes(
        intelligence = 7,
        strength = 3,
        endurance = 10
    )
    val name = "Rikachu"
     val expectedCreature = Creature(attributes, 84, name)
   }

We use an intelligence value of 7, strength of 3, and endurance of 10. The resulting hitPoints from the hitPoint formula are 84, so we can create an expectedCreature that we give a name of Rikachu, a raywenderlich version of Pikachu. We can now perform the action we’re testing on the generator, and assert that the result is equal to expectedCreature.

 assertEquals(expectedCreature, creatureGenerator.generateCreature(attributes, name))

In the CreatureGenerator class, create a shell of the generateCreature() method so that we can run the failing test.


class CreatureGenerator {
    
   fun generateCreature(attributes: CreatureAttributes, name: String = "", drawable: Int = 0): Creature {
     return Creature()
  }
}

The creature constructor has default values for it’s properties. We can run the test class now and see the expected failure, since we’ve not added the hitPoints calculation yet. Now, we can add the hitPoints calculation to CreatureGenerator and return the generated Creature.

    val hitPoints = 5 * attributes.intelligence +
        3 * attributes.strength +
        4 * attributes.endurance
    return Creature(attributes, hitPoints, name, drawable)

Finally, we can run our CreatureGenerator test again, and see a green passing test. With our Creature model class setup, in the next video, we’ll start building out the repository in which we’ll save the Creature data.