Please conduct the following tasks alone. For implementation details you can refer to the lecture slides or the Android developer website. Please do not hesitate to ask me or the tutor if you have any questions.
assignmentCode/assignment2 from the course repository into the assignment2 folder of
your Git repository and open it in Android Studio. The starter is the result of assignment 1 without the counter,
plus the data model and two stubbed composables.MovieList: a LazyColumn that shows one MovieItem per movie of the list.MovieItem: a Column with three Texts (title, year, actor) and the test tag movieItem.app/src/main/java/de/hdmstuttgart/movietracker/
├── MainActivity.kt sets the content, contains MovieList() and MovieItem() with TODOs
├── model/Movie.kt data class Movie(title, year, actor)
└── ui/theme/ Material 3 theme generated by Android Studio
app/src/androidTest/.../Assignment2Test.kt the UI test
The data model:
data class Movie(
val title: String,
val year: String,
val actor: String
)
MovieList already holds the movies in a mutableStateListOf<Movie>(). In contrast to a normal MutableList,
Compose observes this list and recomposes the LazyColumn automatically when an item is added or removed.
Every item shows title, year and actor and is separated from the next one by a HorizontalDivider:
LazyColumn { items(items = movieList) { movie -> MovieItem(...) } } creates the items lazily, i.e. only the
visible ones are composed.Modifier.testTag("movieItem") marks the item for the test, Modifier.clickable { ... } makes it clickable.
The order of modifiers matters.MovieItem gets the click handler as parameter (onMovieClick: (Movie) -> Unit). The removal itself happens in
MovieList, which owns the list: movieList.remove(movie).The starter contains this data, do not change it (the test checks the titles):
| title | year | actor |
|---|---|---|
| Dr. No | 1962 | Sean Connery |
| From Russia with Love | 1963 | Sean Connery |
| Goldfinger | 1964 | Sean Connery |
| Thunderball | 1965 | Sean Connery |
| You Only Live Twice | 1967 | Sean Connery |
The test is part of the starter (app/src/androidTest/java/de/hdmstuttgart/movietracker/Assignment2Test.kt). It
checks the order of the items and that clicking the first item removes it:
package de.hdmstuttgart.movietracker
import androidx.compose.ui.test.assertTextContains
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onAllNodesWithTag
import androidx.compose.ui.test.performClick
import org.junit.Rule
import org.junit.Test
class Assignment2Test {
@get:Rule
val composeTestRule = createAndroidComposeRule<MainActivity>()
@Test
fun myTest() {
composeTestRule.onAllNodesWithTag("movieItem")[0].assertTextContains("Dr. No")
composeTestRule.onAllNodesWithTag("movieItem")[1].assertTextContains("From Russia with Love")
composeTestRule.onAllNodesWithTag("movieItem")[2].assertTextContains("Goldfinger")
composeTestRule.onAllNodesWithTag("movieItem")[3].assertTextContains("Thunderball")
composeTestRule.onAllNodesWithTag("movieItem")[4].assertTextContains("You Only Live Twice")
composeTestRule.onAllNodesWithTag("movieItem")[0].performClick()
composeTestRule.onAllNodesWithTag("movieItem")[0].assertTextContains("From Russia with Love")
composeTestRule.onAllNodesWithTag("movieItem")[0].performClick()
composeTestRule.onAllNodesWithTag("movieItem")[0].assertTextContains("Goldfinger")
}
}
assignment2 folder of your Git repository (assignment2/app/src/main/...)..gitignore: no build/, .gradle/, .idea/ or local.properties.Assignment2Test.kt is replaced by the reference version and executed on a fresh emulator.