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.
finish()
call) and show all saved movies in MainActivity homeRecyclerView. Order MainActivity search results by time added. First clicked results are on top of list.To pass data between activities, use a Singleton pattern. Example implementation of MovieDb class to access search result list
package de.hdmstuttgart.movietracker
class MovieDb private constructor() {
var savedMovies: List<MovieViewModel> = ArrayList()
companion object {
@Volatile
private var instance: MovieDb? = null
fun getInstance() =
instance ?: synchronized(this) {
instance ?: MovieDb().also { instance = it }
}
}
}
Call MovieDb.getInstance().savedMovies.xxx
to access instance of saved movies
On app start
With single saved movie
With multipe saved moviews
On activity start
With search result
Use this data to fill out your rows:
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 |
package de.hdmstuttgart.movietracker
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.closeSoftKeyboard
import androidx.test.espresso.action.ViewActions.replaceText
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.core.internal.deps.guava.base.Preconditions
import androidx.test.espresso.matcher.BoundedMatcher
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.filters.LargeTest
import org.hamcrest.Description
import org.hamcrest.Matcher
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@LargeTest
@RunWith(androidx.test.ext.junit.runners.AndroidJUnit4::class)
class Assignment3Test {
@get:Rule
var activityScenarioRule = ActivityScenarioRule(
MainActivity::class.java
)
@Test
fun assignment3Test() {
onView(withId(R.id.searchBtn))
.perform(click())
onView(withId(R.id.searchMovieTitleEditText))
.perform(replaceText("Gold"), closeSoftKeyboard())
onView(withId(R.id.searchMovieTitleButton))
.perform(click())
onView(withId(R.id.searchRecyclerView))
.check(matches(atPosition(0, hasDescendant(withText("Goldfinger")))))
onView(withId(R.id.searchRecyclerView))
.perform(
RecyclerViewActions.actionOnItemAtPosition<MovieAdapter.ViewHolder>(
0,
click()
)
)
onView(withId(R.id.homeRecyclerView))
.check(matches(atPosition(0, hasDescendant(withText("Goldfinger")))))
onView(withId(R.id.searchBtn))
.perform(click())
onView(withId(R.id.searchMovieTitleEditText))
.perform(replaceText("uss"), closeSoftKeyboard())
onView(withId(R.id.searchMovieTitleButton))
.perform(click())
onView(withId(R.id.searchRecyclerView))
.check(matches(atPosition(0, hasDescendant(withText("From Russia with Love")))))
onView(withId(R.id.searchRecyclerView))
.perform(
RecyclerViewActions.actionOnItemAtPosition<MovieAdapter.ViewHolder>(
0,
click()
)
)
onView(withId(R.id.homeRecyclerView))
.check(matches(atPosition(1, hasDescendant(withText("From Russia with Love")))))
onView(withId(R.id.homeRecyclerView))
.perform(
RecyclerViewActions.actionOnItemAtPosition<MovieAdapter.ViewHolder>(
0,
click()
)
)
onView(withId(R.id.homeRecyclerView))
.check(matches(atPosition(0, hasDescendant(withText("From Russia with Love")))))
}
companion object {
fun atPosition(
position: Int,
itemMatcher: Matcher<View?>
): BoundedMatcher<View?, RecyclerView> {
Preconditions.checkNotNull(itemMatcher)
return object : BoundedMatcher<View?, RecyclerView>(RecyclerView::class.java) {
override fun describeTo(description: Description) {
description.appendText("has item at position $position: ")
itemMatcher.describeTo(description)
}
override fun matchesSafely(view: RecyclerView): Boolean {
val viewHolder = view.findViewHolderForAdapterPosition(position)
?: // has no item on such position
return false
return itemMatcher.matches(viewHolder.itemView)
}
}
}
}
}
dependencies {
implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.9.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.recyclerview:recyclerview:1.3.1")
implementation("androidx.test.espresso:espresso-contrib:3.5.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}