mirror of
https://github.com/hmalik144/Weather-apps.git
synced 2025-12-10 02:05:20 +00:00
- Popup for google playstore permissions added
- UI tests with stubbing added - linting clean ups - changes to fragments and base fragment Took 3 hours 57 minutes
This commit is contained in:
97
.gitignore
vendored
97
.gitignore
vendored
@@ -1,11 +1,90 @@
|
|||||||
*.iml
|
### AndroidStudio ###
|
||||||
|
# Covers files to be ignored for android development using Android Studio.
|
||||||
|
|
||||||
|
# Built application files
|
||||||
|
*.apk
|
||||||
|
*.ap_
|
||||||
|
*.aab
|
||||||
|
|
||||||
|
# Files for the ART/Dalvik VM
|
||||||
|
*.dex
|
||||||
|
|
||||||
|
# Java class files
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
bin/
|
||||||
|
gen/
|
||||||
|
out/
|
||||||
|
|
||||||
|
# Gradle files
|
||||||
.gradle
|
.gradle
|
||||||
/local.properties
|
.gradle/
|
||||||
/.idea/workspace.xml
|
build/
|
||||||
/.idea/libraries
|
|
||||||
/.idea/caches
|
# Signing files
|
||||||
.DS_Store
|
.signing/
|
||||||
/build
|
|
||||||
/captures
|
# Local configuration file (sdk path, etc)
|
||||||
|
local.properties
|
||||||
|
|
||||||
|
# Proguard folder generated by Eclipse
|
||||||
|
proguard/
|
||||||
|
|
||||||
|
# Log Files
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Android Studio
|
||||||
|
/*/build/
|
||||||
|
/*/local.properties
|
||||||
|
/*/out
|
||||||
|
/*/*/build
|
||||||
|
/*/*/production
|
||||||
|
captures/
|
||||||
|
.navigation/
|
||||||
|
*.ipr
|
||||||
|
*~
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
# Keystore files
|
||||||
|
*.jks
|
||||||
|
*.keystore
|
||||||
|
|
||||||
|
# Google Services (e.g. APIs or Firebase)
|
||||||
|
# google-services.json
|
||||||
|
|
||||||
|
# Android Patch
|
||||||
|
gen-external-apklibs
|
||||||
|
|
||||||
|
# External native build folder generated in Android Studio 2.2 and later
|
||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
/projectFilesBackup
|
|
||||||
|
# IntelliJ IDEA
|
||||||
|
*.iml
|
||||||
|
*.iws
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# User-specific configurations
|
||||||
|
.idea/caches/
|
||||||
|
.idea/libraries/
|
||||||
|
.idea/shelf/
|
||||||
|
.idea/workspace.xml
|
||||||
|
.idea/tasks.xml
|
||||||
|
.idea/.name
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/copyright/profiles_settings.xml
|
||||||
|
.idea/encodings.xml
|
||||||
|
.idea/misc.xml
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/scopes/scope_settings.xml
|
||||||
|
.idea/dictionaries
|
||||||
|
.idea/vcs.xml
|
||||||
|
.idea/jsLibraryMappings.xml
|
||||||
|
.idea/datasources.xml
|
||||||
|
.idea/dataSources.ids
|
||||||
|
.idea/sqlDataSources.xml
|
||||||
|
.idea/dynamic.xml
|
||||||
|
.idea/uiDesigner.xml
|
||||||
|
.idea/assetWizardSettings.xml
|
||||||
|
.idea/gradle.xml
|
||||||
|
.idea/jarRepositorie
|
||||||
|
|||||||
BIN
.idea/caches/build_file_checksums.ser
generated
BIN
.idea/caches/build_file_checksums.ser
generated
Binary file not shown.
20
.idea/gradle.xml
generated
20
.idea/gradle.xml
generated
@@ -1,20 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
|
||||||
<component name="GradleSettings">
|
|
||||||
<option name="linkedExternalProjectsSettings">
|
|
||||||
<GradleProjectSettings>
|
|
||||||
<option name="testRunner" value="PLATFORM" />
|
|
||||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="modules">
|
|
||||||
<set>
|
|
||||||
<option value="$PROJECT_DIR$" />
|
|
||||||
<option value="$PROJECT_DIR$/app" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
<option name="resolveModulePerSourceSet" value="false" />
|
|
||||||
</GradleProjectSettings>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
48
.idea/misc.xml
generated
48
.idea/misc.xml
generated
@@ -1,48 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="NullableNotNullManager">
|
|
||||||
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
|
|
||||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
|
||||||
<option name="myNullables">
|
|
||||||
<value>
|
|
||||||
<list size="12">
|
|
||||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
|
|
||||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
|
|
||||||
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
|
|
||||||
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
|
|
||||||
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
|
|
||||||
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
|
|
||||||
<item index="6" class="java.lang.String" itemvalue="android.annotation.Nullable" />
|
|
||||||
<item index="7" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
|
|
||||||
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
|
|
||||||
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
|
|
||||||
<item index="10" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
|
|
||||||
<item index="11" class="java.lang.String" itemvalue="com.android.annotations.Nullable" />
|
|
||||||
</list>
|
|
||||||
</value>
|
|
||||||
</option>
|
|
||||||
<option name="myNotNulls">
|
|
||||||
<value>
|
|
||||||
<list size="11">
|
|
||||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
|
||||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
|
||||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
|
||||||
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
|
|
||||||
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
|
|
||||||
<item index="5" class="java.lang.String" itemvalue="android.annotation.NonNull" />
|
|
||||||
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
|
|
||||||
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
|
|
||||||
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
|
|
||||||
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
|
|
||||||
<item index="10" class="java.lang.String" itemvalue="com.android.annotations.NonNull" />
|
|
||||||
</list>
|
|
||||||
</value>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectType">
|
|
||||||
<option name="id" value="Android" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
11
.idea/modules.xml
generated
11
.idea/modules.xml
generated
@@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/Altas_-_Weather.iml" filepath="$PROJECT_DIR$/.idea/modules/Altas_-_Weather.iml" group="Altas_-_Weather" />
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/modules/app/Altas_-_Weather-app.iml" filepath="$PROJECT_DIR$/.idea/modules/app/Altas_-_Weather-app.iml" group="Altas_-_Weather/app" />
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/Weather_app.iml" filepath="$PROJECT_DIR$/Weather_app.iml" />
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
12
.idea/runConfigurations.xml
generated
12
.idea/runConfigurations.xml
generated
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RunConfigurationProducerService">
|
|
||||||
<option name="ignoredProducers">
|
|
||||||
<set>
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@@ -97,6 +97,7 @@ dependencies {
|
|||||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2'
|
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2'
|
||||||
implementation 'androidx.navigation:navigation-ui-ktx:2.3.2'
|
implementation 'androidx.navigation:navigation-ui-ktx:2.3.2'
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
|
||||||
|
implementation 'androidx.test.espresso:espresso-idling-resource:3.4.0'
|
||||||
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2'
|
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.2'
|
||||||
androidTestImplementation 'com.android.support.test:rules:1.0.2'
|
androidTestImplementation 'com.android.support.test:rules:1.0.2'
|
||||||
// Unit testing
|
// Unit testing
|
||||||
@@ -108,8 +109,8 @@ dependencies {
|
|||||||
|
|
||||||
// android unit testing and espresso
|
// android unit testing and espresso
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||||
implementation 'androidx.test.espresso:espresso-core:3.2.0'
|
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||||
|
androidTestImplementation 'androidx.test:rules:1.4.1-alpha06'
|
||||||
//mock websever for testing retrofit responses
|
//mock websever for testing retrofit responses
|
||||||
testImplementation "com.squareup.okhttp3:mockwebserver:4.6.0"
|
testImplementation "com.squareup.okhttp3:mockwebserver:4.6.0"
|
||||||
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
|
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
|
||||||
@@ -117,7 +118,6 @@ dependencies {
|
|||||||
//mockito and livedata testing
|
//mockito and livedata testing
|
||||||
testImplementation 'org.mockito:mockito-inline:2.13.0'
|
testImplementation 'org.mockito:mockito-inline:2.13.0'
|
||||||
implementation 'android.arch.core:core-testing'
|
implementation 'android.arch.core:core-testing'
|
||||||
androidTestImplementation 'androidx.test:rules:1.3.0-rc01'
|
|
||||||
|
|
||||||
// Mockk
|
// Mockk
|
||||||
def mockk_ver = "1.10.5"
|
def mockk_ver = "1.10.5"
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
package com.appttude.h_mal.atlas_weather.application
|
package com.appttude.h_mal.atlas_weather.application
|
||||||
|
|
||||||
|
import androidx.room.Room
|
||||||
import androidx.test.espresso.IdlingRegistry
|
import androidx.test.espresso.IdlingRegistry
|
||||||
import androidx.test.espresso.idling.CountingIdlingResource
|
import androidx.test.espresso.idling.CountingIdlingResource
|
||||||
import com.appttude.h_mal.atlas_weather.R
|
|
||||||
import com.appttude.h_mal.atlas_weather.data.location.MockLocationProvider
|
import com.appttude.h_mal.atlas_weather.data.location.MockLocationProvider
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.Api
|
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.NetworkModule
|
import com.appttude.h_mal.atlas_weather.data.network.NetworkModule
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.WeatherApi
|
import com.appttude.h_mal.atlas_weather.data.network.WeatherApi
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.interceptors.MockingNetworkInterceptor
|
import com.appttude.h_mal.atlas_weather.data.network.interceptors.MockingNetworkInterceptor
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.interceptors.NetworkConnectionInterceptor
|
import com.appttude.h_mal.atlas_weather.data.network.interceptors.NetworkConnectionInterceptor
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.interceptors.QueryParamsInterceptor
|
import com.appttude.h_mal.atlas_weather.data.network.interceptors.QueryParamsInterceptor
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.networkUtils.loggingInterceptor
|
import com.appttude.h_mal.atlas_weather.data.network.networkUtils.loggingInterceptor
|
||||||
|
import com.appttude.h_mal.atlas_weather.data.room.AppDatabase
|
||||||
|
import com.appttude.h_mal.atlas_weather.data.room.Converter
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
|
|
||||||
class TestAppClass : BaseAppClass() {
|
class TestAppClass : BaseAppClass() {
|
||||||
@@ -22,17 +23,23 @@ class TestAppClass : BaseAppClass() {
|
|||||||
IdlingRegistry.getInstance().register(idlingResources)
|
IdlingRegistry.getInstance().register(idlingResources)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createNetworkModule(): Api {
|
override fun createNetworkModule(): WeatherApi {
|
||||||
return NetworkModule().invoke<WeatherApi>(
|
return NetworkModule().invoke<WeatherApi>(
|
||||||
|
mockingNetworkInterceptor,
|
||||||
NetworkConnectionInterceptor(this),
|
NetworkConnectionInterceptor(this),
|
||||||
QueryParamsInterceptor(),
|
QueryParamsInterceptor(),
|
||||||
loggingInterceptor,
|
loggingInterceptor
|
||||||
mockingNetworkInterceptor
|
) as WeatherApi
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createLocationModule() = MockLocationProvider()
|
override fun createLocationModule() = MockLocationProvider()
|
||||||
|
|
||||||
|
override fun createRoomDatabase(): AppDatabase {
|
||||||
|
return Room.inMemoryDatabaseBuilder(this, AppDatabase::class.java)
|
||||||
|
.addTypeConverter(Converter(this))
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
fun stubUrl(url: String, rawPath: String) {
|
fun stubUrl(url: String, rawPath: String) {
|
||||||
val id = resources.getIdentifier(rawPath, "raw", packageName)
|
val id = resources.getIdentifier(rawPath, "raw", packageName)
|
||||||
val iStream = resources.openRawResource(id)
|
val iStream = resources.openRawResource(id)
|
||||||
@@ -40,7 +47,7 @@ class TestAppClass : BaseAppClass() {
|
|||||||
mockingNetworkInterceptor.addUrlStub(url = url, data = data)
|
mockingNetworkInterceptor.addUrlStub(url = url, data = data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeUrlStub(url: String){
|
fun removeUrlStub(url: String) {
|
||||||
mockingNetworkInterceptor.removeUrlStub(url = url)
|
mockingNetworkInterceptor.removeUrlStub(url = url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
package com.appttude.h_mal.atlas_weather.monoWeather.testsuite
|
package com.appttude.h_mal.atlas_weather.monoWeather.testsuite
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.test.espresso.Espresso.onView
|
||||||
|
import androidx.test.espresso.action.ViewActions
|
||||||
|
import androidx.test.espresso.action.ViewActions.pressBack
|
||||||
|
import androidx.test.espresso.assertion.ViewAssertions.matches
|
||||||
|
import androidx.test.espresso.matcher.RootMatchers.isDialog
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers.*
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
import androidx.test.rule.ActivityTestRule
|
import androidx.test.rule.ActivityTestRule
|
||||||
import com.appttude.h_mal.atlas_weather.application.TestAppClass
|
import com.appttude.h_mal.atlas_weather.application.TestAppClass
|
||||||
@@ -21,6 +28,12 @@ open class BaseTest {
|
|||||||
testApp = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as TestAppClass
|
testApp = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as TestAppClass
|
||||||
setupFeed()
|
setupFeed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun afterActivityLaunched() {
|
||||||
|
|
||||||
|
// Dismiss dialog
|
||||||
|
onView(withText("AGREE")).inRoot(isDialog()).check(matches(isDisplayed())).perform(ViewActions.click())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stubEndpoint(url: String, stub: Stubs) {
|
fun stubEndpoint(url: String, stub: Stubs) {
|
||||||
@@ -32,8 +45,7 @@ open class BaseTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
fun tearDown() {
|
fun tearDown() {}
|
||||||
}
|
|
||||||
|
|
||||||
open fun setupFeed() {}
|
open fun setupFeed() {}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,11 @@
|
|||||||
package com.appttude.h_mal.atlas_weather.monoWeather.testsuite
|
package com.appttude.h_mal.atlas_weather.monoWeather.testsuite
|
||||||
|
|
||||||
|
|
||||||
|
import androidx.test.espresso.Espresso
|
||||||
|
import androidx.test.espresso.action.ViewActions
|
||||||
|
import androidx.test.espresso.assertion.ViewAssertions
|
||||||
|
import androidx.test.espresso.matcher.RootMatchers
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers
|
||||||
import androidx.test.rule.GrantPermissionRule
|
import androidx.test.rule.GrantPermissionRule
|
||||||
import com.appttude.h_mal.atlas_weather.monoWeather.robot.homeScreen
|
import com.appttude.h_mal.atlas_weather.monoWeather.robot.homeScreen
|
||||||
import com.appttude.h_mal.atlas_weather.utils.Stubs
|
import com.appttude.h_mal.atlas_weather.utils.Stubs
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package com.appttude.h_mal.atlas_weather.monoWeather.testsuite
|
||||||
|
|
||||||
|
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.test.core.app.ActivityScenario
|
||||||
|
import androidx.test.core.app.ActivityScenario.launch
|
||||||
|
import androidx.test.espresso.Espresso
|
||||||
|
import androidx.test.espresso.action.ViewActions
|
||||||
|
import androidx.test.espresso.assertion.ViewAssertions
|
||||||
|
import androidx.test.espresso.matcher.RootMatchers
|
||||||
|
import androidx.test.espresso.matcher.ViewMatchers
|
||||||
|
import androidx.test.ext.junit.rules.ActivityScenarioRule
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
|
||||||
|
import androidx.test.rule.GrantPermissionRule
|
||||||
|
import com.appttude.h_mal.atlas_weather.application.TestAppClass
|
||||||
|
import com.appttude.h_mal.atlas_weather.monoWeather.robot.homeScreen
|
||||||
|
import com.appttude.h_mal.atlas_weather.monoWeather.ui.MainActivity
|
||||||
|
import com.appttude.h_mal.atlas_weather.utils.Stubs
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4ClassRunner::class)
|
||||||
|
class HomePageUITestScenario : BaseMainScenario() {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
@JvmField
|
||||||
|
var mGrantPermissionRule: GrantPermissionRule =
|
||||||
|
GrantPermissionRule.grant(
|
||||||
|
"android.permission.ACCESS_COARSE_LOCATION")
|
||||||
|
|
||||||
|
override fun setupFeed() {
|
||||||
|
stubEndpoint("https://api.openweathermap.org/data/2.5/onecall", Stubs.Valid)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun loadApp_validWeatherResponse_returnsValidPage() {
|
||||||
|
homeScreen {
|
||||||
|
verifyCurrentTemperature(2)
|
||||||
|
verifyCurrentLocation("Mock Location")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class BaseMainScenario {
|
||||||
|
|
||||||
|
lateinit var scenario: ActivityScenario<MainActivity>
|
||||||
|
private lateinit var testApp : TestAppClass
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
scenario = launch(MainActivity::class.java)
|
||||||
|
scenario.moveToState(Lifecycle.State.INITIALIZED)
|
||||||
|
scenario.onActivity {
|
||||||
|
runBlocking {
|
||||||
|
testApp = it.application as TestAppClass
|
||||||
|
setupFeed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scenario.moveToState(Lifecycle.State.CREATED).onActivity {
|
||||||
|
Espresso.onView(ViewMatchers.withText("AGREE"))
|
||||||
|
.inRoot(RootMatchers.isDialog())
|
||||||
|
.check(ViewAssertions.matches(ViewMatchers.isDisplayed()))
|
||||||
|
.perform(ViewActions.click())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stubEndpoint(url: String, stub: Stubs) {
|
||||||
|
testApp.stubUrl(url, stub.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unstubEndpoint(url: String) {
|
||||||
|
testApp.removeUrlStub(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun tearDown() {}
|
||||||
|
|
||||||
|
open fun setupFeed() {}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.appttude.h_mal.atlas_weather.application
|
package com.appttude.h_mal.atlas_weather.application
|
||||||
|
|
||||||
|
import androidx.room.RoomDatabase
|
||||||
import com.appttude.h_mal.atlas_weather.data.location.LocationProvider
|
import com.appttude.h_mal.atlas_weather.data.location.LocationProvider
|
||||||
import com.appttude.h_mal.atlas_weather.data.location.LocationProviderImpl
|
import com.appttude.h_mal.atlas_weather.data.location.LocationProviderImpl
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.Api
|
import com.appttude.h_mal.atlas_weather.data.network.Api
|
||||||
@@ -26,14 +27,16 @@ const val LOCATION_PERMISSION_REQUEST = 505
|
|||||||
|
|
||||||
class AppClass : BaseAppClass() {
|
class AppClass : BaseAppClass() {
|
||||||
|
|
||||||
override fun createNetworkModule(): Api {
|
override fun createNetworkModule(): WeatherApi {
|
||||||
return NetworkModule().invoke<WeatherApi>(
|
return NetworkModule().invoke<WeatherApi>(
|
||||||
NetworkConnectionInterceptor(this),
|
NetworkConnectionInterceptor(this),
|
||||||
QueryParamsInterceptor(),
|
QueryParamsInterceptor(),
|
||||||
loggingInterceptor
|
loggingInterceptor
|
||||||
)
|
) as WeatherApi
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createLocationModule() = LocationProviderImpl(this)
|
override fun createLocationModule() = LocationProviderImpl(this)
|
||||||
|
|
||||||
|
override fun createRoomDatabase(): AppDatabase = AppDatabase(this)
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,8 @@
|
|||||||
package com.appttude.h_mal.atlas_weather.application
|
package com.appttude.h_mal.atlas_weather.application
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import androidx.test.espresso.idling.CountingIdlingResource
|
|
||||||
import com.appttude.h_mal.atlas_weather.data.location.LocationProvider
|
import com.appttude.h_mal.atlas_weather.data.location.LocationProvider
|
||||||
import com.appttude.h_mal.atlas_weather.data.location.LocationProviderImpl
|
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.Api
|
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.NetworkModule
|
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.WeatherApi
|
import com.appttude.h_mal.atlas_weather.data.network.WeatherApi
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.interceptors.NetworkConnectionInterceptor
|
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.interceptors.QueryParamsInterceptor
|
|
||||||
import com.appttude.h_mal.atlas_weather.data.network.networkUtils.loggingInterceptor
|
|
||||||
import com.appttude.h_mal.atlas_weather.data.prefs.PreferenceProvider
|
import com.appttude.h_mal.atlas_weather.data.prefs.PreferenceProvider
|
||||||
import com.appttude.h_mal.atlas_weather.data.repository.RepositoryImpl
|
import com.appttude.h_mal.atlas_weather.data.repository.RepositoryImpl
|
||||||
import com.appttude.h_mal.atlas_weather.data.repository.SettingsRepositoryImpl
|
import com.appttude.h_mal.atlas_weather.data.repository.SettingsRepositoryImpl
|
||||||
@@ -31,11 +24,11 @@ abstract class BaseAppClass : Application(), KodeinAware {
|
|||||||
override val kodein = Kodein.lazy {
|
override val kodein = Kodein.lazy {
|
||||||
import(androidXModule(this@BaseAppClass))
|
import(androidXModule(this@BaseAppClass))
|
||||||
|
|
||||||
bind() from singleton { createNetworkModule() as WeatherApi}
|
bind() from singleton { createNetworkModule() }
|
||||||
bind() from singleton { createLocationModule() }
|
bind() from singleton { createLocationModule() }
|
||||||
|
|
||||||
bind() from singleton { Gson() }
|
bind() from singleton { Gson() }
|
||||||
bind() from singleton { AppDatabase(instance()) }
|
bind() from singleton { createRoomDatabase() }
|
||||||
bind() from singleton { PreferenceProvider(instance()) }
|
bind() from singleton { PreferenceProvider(instance()) }
|
||||||
bind() from singleton { RepositoryImpl(instance(), instance(), instance()) }
|
bind() from singleton { RepositoryImpl(instance(), instance(), instance()) }
|
||||||
bind() from singleton { SettingsRepositoryImpl(instance()) }
|
bind() from singleton { SettingsRepositoryImpl(instance()) }
|
||||||
@@ -43,7 +36,8 @@ abstract class BaseAppClass : Application(), KodeinAware {
|
|||||||
bind() from provider { ApplicationViewModelFactory(instance(), instance()) }
|
bind() from provider { ApplicationViewModelFactory(instance(), instance()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun createNetworkModule() : Api
|
abstract fun createNetworkModule(): WeatherApi
|
||||||
abstract fun createLocationModule() : LocationProvider
|
abstract fun createLocationModule(): LocationProvider
|
||||||
|
abstract fun createRoomDatabase(): AppDatabase
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -10,19 +10,18 @@ import org.kodein.di.android.kodein
|
|||||||
import org.kodein.di.generic.instance
|
import org.kodein.di.generic.instance
|
||||||
|
|
||||||
@ProvidedTypeConverter
|
@ProvidedTypeConverter
|
||||||
class Converter(context: Context): KodeinAware{
|
class Converter(context: Context) : KodeinAware {
|
||||||
override val kodein by kodein(context)
|
override val kodein by kodein(context)
|
||||||
private val gson by instance<Gson>()
|
private val gson by instance<Gson>()
|
||||||
|
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
fun fullWeatherToString(fullWeather: FullWeather): String{
|
fun fullWeatherToString(fullWeather: FullWeather): String {
|
||||||
return gson.toJson(fullWeather)
|
return gson.toJson(fullWeather)
|
||||||
}
|
}
|
||||||
|
|
||||||
@TypeConverter
|
@TypeConverter
|
||||||
fun stringToFullWeather(string: String): FullWeather{
|
fun stringToFullWeather(string: String): FullWeather {
|
||||||
return gson.fromJson(string, FullWeather::class.java)
|
return gson.fromJson(string, FullWeather::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ abstract class BaseDeclarationDialog(val context: Context): DeclarationBuilder {
|
|||||||
abstract override val link: String
|
abstract override val link: String
|
||||||
abstract override val message: String
|
abstract override val message: String
|
||||||
|
|
||||||
fun showDialog(agreeCallback: () -> Unit = { Unit }, disagreeCallback: () -> Unit = { Unit }) {
|
fun showDialog(agreeCallback: () -> Unit = { }, disagreeCallback: () -> Unit = { Unit }) {
|
||||||
val myMessage = buildMessage()
|
val myMessage = buildMessage()
|
||||||
|
|
||||||
val builder = AlertDialog.Builder(context)
|
val builder = AlertDialog.Builder(context)
|
||||||
|
|||||||
@@ -2,15 +2,18 @@ package com.appttude.h_mal.atlas_weather.monoWeather.ui
|
|||||||
|
|
||||||
import android.animation.Animator
|
import android.animation.Animator
|
||||||
import android.animation.AnimatorListenerAdapter
|
import android.animation.AnimatorListenerAdapter
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.annotation.LayoutRes
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
import com.appttude.h_mal.atlas_weather.application.LOCATION_PERMISSION_REQUEST
|
||||||
import com.appttude.h_mal.atlas_weather.utils.Event
|
import com.appttude.h_mal.atlas_weather.utils.Event
|
||||||
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
import com.appttude.h_mal.atlas_weather.utils.displayToast
|
||||||
import com.appttude.h_mal.atlas_weather.utils.hide
|
import com.appttude.h_mal.atlas_weather.utils.hide
|
||||||
@@ -24,7 +27,7 @@ import org.kodein.di.android.x.kodein
|
|||||||
import org.kodein.di.generic.instance
|
import org.kodein.di.generic.instance
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
abstract class BaseFragment : Fragment(), KodeinAware {
|
abstract class BaseFragment(@LayoutRes contentLayoutId: Int) : Fragment(contentLayoutId), KodeinAware {
|
||||||
|
|
||||||
override val kodein by kodein()
|
override val kodein by kodein()
|
||||||
val factory by instance<ApplicationViewModelFactory>()
|
val factory by instance<ApplicationViewModelFactory>()
|
||||||
@@ -119,4 +122,21 @@ abstract class BaseFragment : Fragment(), KodeinAware {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
|
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String?>, grantResults: IntArray) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
|
if (requestCode == LOCATION_PERMISSION_REQUEST) {
|
||||||
|
if (grantResults.isNotEmpty() &&
|
||||||
|
grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
permissionsGranted()
|
||||||
|
displayToast("Permission granted")
|
||||||
|
} else {
|
||||||
|
permissionsRefused()
|
||||||
|
displayToast("Permission denied")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun permissionsGranted() {}
|
||||||
|
open fun permissionsRefused() {}
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@ import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
|||||||
import kotlinx.android.synthetic.main.fragment_home.*
|
import kotlinx.android.synthetic.main.fragment_home.*
|
||||||
|
|
||||||
|
|
||||||
class WorldItemFragment : BaseFragment() {
|
class WorldItemFragment : BaseFragment(R.layout.fragment_home) {
|
||||||
|
|
||||||
private val viewModel by getFragmentViewModel<WorldViewModel>()
|
private val viewModel by getFragmentViewModel<WorldViewModel>()
|
||||||
private var param1: String? = null
|
private var param1: String? = null
|
||||||
@@ -24,12 +24,6 @@ class WorldItemFragment : BaseFragment() {
|
|||||||
param1 = WorldItemFragmentArgs.fromBundle(requireArguments()).locationName
|
param1 = WorldItemFragmentArgs.fromBundle(requireArguments()).locationName
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?): View? {
|
|
||||||
// Inflate the layout for this fragment
|
|
||||||
return inflater.inflate(R.layout.fragment_home, container, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.appttude.h_mal.atlas_weather.monoWeather.ui.home
|
package com.appttude.h_mal.atlas_weather.monoWeather.ui.home
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
|
import android.Manifest.permission.ACCESS_COARSE_LOCATION
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -11,6 +12,7 @@ import androidx.fragment.app.Fragment
|
|||||||
import androidx.lifecycle.observe
|
import androidx.lifecycle.observe
|
||||||
import com.appttude.h_mal.atlas_weather.R
|
import com.appttude.h_mal.atlas_weather.R
|
||||||
import com.appttude.h_mal.atlas_weather.application.LOCATION_PERMISSION_REQUEST
|
import com.appttude.h_mal.atlas_weather.application.LOCATION_PERMISSION_REQUEST
|
||||||
|
import com.appttude.h_mal.atlas_weather.model.forecast.Forecast
|
||||||
import com.appttude.h_mal.atlas_weather.monoWeather.dialog.PermissionsDeclarationDialog
|
import com.appttude.h_mal.atlas_weather.monoWeather.dialog.PermissionsDeclarationDialog
|
||||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.BaseFragment
|
import com.appttude.h_mal.atlas_weather.monoWeather.ui.BaseFragment
|
||||||
import com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter.WeatherRecyclerAdapter
|
import com.appttude.h_mal.atlas_weather.monoWeather.ui.home.adapter.WeatherRecyclerAdapter
|
||||||
@@ -24,36 +26,29 @@ import kotlinx.android.synthetic.main.fragment_home.*
|
|||||||
* A simple [Fragment] subclass.
|
* A simple [Fragment] subclass.
|
||||||
* create an instance of this fragment.
|
* create an instance of this fragment.
|
||||||
*/
|
*/
|
||||||
class HomeFragment : BaseFragment() {
|
class HomeFragment : BaseFragment(R.layout.fragment_home) {
|
||||||
|
|
||||||
private val viewModel by getFragmentViewModel<MainViewModel>()
|
private val viewModel by getFragmentViewModel<MainViewModel>()
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?): View? {
|
|
||||||
return inflater.inflate(R.layout.fragment_home, container, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
val recyclerAdapter = WeatherRecyclerAdapter {
|
val recyclerAdapter = WeatherRecyclerAdapter(itemClick = {
|
||||||
val directions =
|
navigateToFurtherDetails(it)
|
||||||
HomeFragmentDirections.actionHomeFragmentToFurtherDetailsFragment(it)
|
})
|
||||||
navigateTo(directions)
|
|
||||||
}
|
|
||||||
|
|
||||||
forecast_listview.adapter = recyclerAdapter
|
forecast_listview.adapter = recyclerAdapter
|
||||||
|
|
||||||
PermissionsDeclarationDialog(requireContext()).showDialog(agreeCallback = {
|
PermissionsDeclarationDialog(requireContext()).showDialog(agreeCallback = {
|
||||||
getPermissionResult(Manifest.permission.ACCESS_COARSE_LOCATION, LOCATION_PERMISSION_REQUEST) {
|
getPermissionResult(ACCESS_COARSE_LOCATION, LOCATION_PERMISSION_REQUEST) {
|
||||||
viewModel.fetchData()
|
viewModel.fetchData()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
swipe_refresh.apply {
|
swipe_refresh.apply {
|
||||||
setOnRefreshListener {
|
setOnRefreshListener {
|
||||||
getPermissionResult(Manifest.permission.ACCESS_COARSE_LOCATION, LOCATION_PERMISSION_REQUEST) {
|
getPermissionResult(ACCESS_COARSE_LOCATION, LOCATION_PERMISSION_REQUEST) {
|
||||||
viewModel.fetchData()
|
viewModel.fetchData()
|
||||||
isRefreshing = true
|
isRefreshing = true
|
||||||
}
|
}
|
||||||
@@ -70,16 +65,13 @@ class HomeFragment : BaseFragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String?>, grantResults: IntArray) {
|
override fun permissionsGranted() {
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
viewModel.fetchData()
|
||||||
if (requestCode == LOCATION_PERMISSION_REQUEST) {
|
}
|
||||||
if (grantResults.isNotEmpty()
|
|
||||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
private fun navigateToFurtherDetails(forecast: Forecast){
|
||||||
viewModel.fetchData()
|
val directions = HomeFragmentDirections
|
||||||
displayToast("Permission granted")
|
.actionHomeFragmentToFurtherDetailsFragment(forecast)
|
||||||
} else {
|
navigateTo(directions)
|
||||||
displayToast("Permission denied")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,16 +14,10 @@ import com.appttude.h_mal.atlas_weather.viewmodel.WorldViewModel
|
|||||||
import kotlinx.android.synthetic.main.activity_add_forecast.*
|
import kotlinx.android.synthetic.main.activity_add_forecast.*
|
||||||
|
|
||||||
|
|
||||||
class AddLocationFragment : BaseFragment() {
|
class AddLocationFragment : BaseFragment(R.layout.activity_add_forecast) {
|
||||||
|
|
||||||
private val viewModel by getFragmentViewModel<WorldViewModel>()
|
private val viewModel by getFragmentViewModel<WorldViewModel>()
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?): View? {
|
|
||||||
// Inflate the layout for this fragment
|
|
||||||
return inflater.inflate(R.layout.activity_add_forecast, container, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import kotlinx.android.synthetic.main.fragment_add_location.world_recycler
|
|||||||
* A simple [Fragment] subclass.
|
* A simple [Fragment] subclass.
|
||||||
* create an instance of this fragment.
|
* create an instance of this fragment.
|
||||||
*/
|
*/
|
||||||
class WorldFragment : BaseFragment() {
|
class WorldFragment : BaseFragment(R.layout.fragment__two) {
|
||||||
private val viewModel by getFragmentViewModel<WorldViewModel>()
|
private val viewModel by getFragmentViewModel<WorldViewModel>()
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@@ -31,12 +31,6 @@ class WorldFragment : BaseFragment() {
|
|||||||
viewModel.fetchAllLocations()
|
viewModel.fetchAllLocations()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?): View? {
|
|
||||||
// Inflate the layout for this fragment
|
|
||||||
return inflater.inflate(R.layout.fragment__two, container, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import com.appttude.h_mal.atlas_weather.utils.generateView
|
|||||||
import com.appttude.h_mal.atlas_weather.utils.loadImage
|
import com.appttude.h_mal.atlas_weather.utils.loadImage
|
||||||
|
|
||||||
class WorldRecyclerAdapter(
|
class WorldRecyclerAdapter(
|
||||||
val itemClick: (WeatherDisplay) -> Unit,
|
private val itemClick: (WeatherDisplay) -> Unit,
|
||||||
val itemLongClick: (String) -> Unit
|
private val itemLongClick: (String) -> Unit
|
||||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
var weather: MutableList<WeatherDisplay> = mutableListOf()
|
var weather: MutableList<WeatherDisplay> = mutableListOf()
|
||||||
|
|
||||||
@@ -78,23 +78,28 @@ class WorldRecyclerAdapter(
|
|||||||
return if (weather.size == 0) 1 else weather.size
|
return if (weather.size == 0) 1 else weather.size
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class WorldHolderCurrent(listItemView: View) : RecyclerView.ViewHolder(listItemView) {
|
internal class WorldHolderCurrent(cellView: View) : BaseViewHolder<WeatherDisplay>(cellView) {
|
||||||
|
|
||||||
var locationTV: TextView = listItemView.findViewById(R.id.db_location)
|
private val locationTV: TextView = cellView.findViewById(R.id.db_location)
|
||||||
var conditionTV: TextView = listItemView.findViewById(R.id.db_condition)
|
private val conditionTV: TextView = cellView.findViewById(R.id.db_condition)
|
||||||
var weatherIV: ImageView = listItemView.findViewById(R.id.db_icon)
|
private val weatherIV: ImageView = cellView.findViewById(R.id.db_icon)
|
||||||
var avgTempTV: TextView = listItemView.findViewById(R.id.db_main_temp)
|
private val avgTempTV: TextView = cellView.findViewById(R.id.db_main_temp)
|
||||||
var tempUnit: TextView = listItemView.findViewById(R.id.db_temp_unit)
|
private val tempUnit: TextView = cellView.findViewById(R.id.db_temp_unit)
|
||||||
|
|
||||||
fun bindData(weather: WeatherDisplay?){
|
override fun bindData(data: WeatherDisplay?){
|
||||||
locationTV.text = weather?.displayName
|
locationTV.text = data?.displayName
|
||||||
conditionTV.text = weather?.description
|
conditionTV.text = data?.description
|
||||||
weatherIV.loadImage(weather?.iconURL)
|
weatherIV.loadImage(data?.iconURL)
|
||||||
avgTempTV.text = weather?.forecast?.get(0)?.mainTemp
|
avgTempTV.text = data?.forecast?.get(0)?.mainTemp
|
||||||
tempUnit.text = itemView.context.getString(R.string.degrees)
|
tempUnit.text = itemView.context.getString(R.string.degrees)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class BaseViewHolder<T : Any>(cellView: View) : RecyclerView.ViewHolder(cellView) {
|
||||||
|
|
||||||
|
abstract fun bindData(data : T?)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user