From 4319ece4f3df5643ca24eee70b50cb1308434842 Mon Sep 17 00:00:00 2001 From: johan12345 Date: Tue, 16 Aug 2022 21:20:03 +0200 Subject: [PATCH] ChargepriceFragment: avoid reloading prices on orientation change using SavedStateHandle --- .../evmap/fragment/ChargepriceFragment.kt | 7 +++--- .../evmap/viewmodel/ChargepriceViewModel.kt | 24 ++++++++++++------- .../net/vonforst/evmap/viewmodel/Utils.kt | 10 ++++++++ 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/net/vonforst/evmap/fragment/ChargepriceFragment.kt b/app/src/main/java/net/vonforst/evmap/fragment/ChargepriceFragment.kt index 11729a33..c5437e14 100644 --- a/app/src/main/java/net/vonforst/evmap/fragment/ChargepriceFragment.kt +++ b/app/src/main/java/net/vonforst/evmap/fragment/ChargepriceFragment.kt @@ -31,7 +31,7 @@ import net.vonforst.evmap.model.Chargepoint import net.vonforst.evmap.storage.PreferenceDataSource import net.vonforst.evmap.viewmodel.ChargepriceViewModel import net.vonforst.evmap.viewmodel.Status -import net.vonforst.evmap.viewmodel.viewModelFactory +import net.vonforst.evmap.viewmodel.savedStateViewModelFactory import java.text.NumberFormat class ChargepriceFragment : Fragment() { @@ -39,10 +39,11 @@ class ChargepriceFragment : Fragment() { private var connectionErrorSnackbar: Snackbar? = null private val vm: ChargepriceViewModel by viewModels(factoryProducer = { - viewModelFactory { + savedStateViewModelFactory { state -> ChargepriceViewModel( requireActivity().application, - getString(R.string.chargeprice_key) + getString(R.string.chargeprice_key), + state ) } }) diff --git a/app/src/main/java/net/vonforst/evmap/viewmodel/ChargepriceViewModel.kt b/app/src/main/java/net/vonforst/evmap/viewmodel/ChargepriceViewModel.kt index 789594a1..28fd742a 100644 --- a/app/src/main/java/net/vonforst/evmap/viewmodel/ChargepriceViewModel.kt +++ b/app/src/main/java/net/vonforst/evmap/viewmodel/ChargepriceViewModel.kt @@ -16,21 +16,25 @@ import net.vonforst.evmap.storage.PreferenceDataSource import retrofit2.HttpException import java.io.IOException -class ChargepriceViewModel(application: Application, chargepriceApiKey: String) : +class ChargepriceViewModel( + application: Application, + chargepriceApiKey: String, + private val state: SavedStateHandle +) : AndroidViewModel(application) { private var api = ChargepriceApi.create(chargepriceApiKey) private var prefs = PreferenceDataSource(application) val charger: MutableLiveData by lazy { - MutableLiveData() + state.getLiveData("charger") } val dataSource: MutableLiveData by lazy { - MutableLiveData() + state.getLiveData("dataSource") } val chargepoint: MutableLiveData by lazy { - MutableLiveData() + state.getLiveData("chargepoint") } private val vehicleIds: MutableLiveData> by lazy { @@ -65,7 +69,7 @@ class ChargepriceViewModel(application: Application, chargepriceApiKey: String) } val vehicle: MutableLiveData by lazy { - MutableLiveData() + state.getLiveData("vehicle") } val vehicleCompatibleConnectors: LiveData> by lazy { @@ -111,9 +115,9 @@ class ChargepriceViewModel(application: Application, chargepriceApiKey: String) } } - val chargePrices: MediatorLiveData>> by lazy { + val chargePrices: MutableLiveData>> by lazy { MediatorLiveData>>().apply { - value = Resource.loading(null) + value = state["chargePrices"] ?: Resource.loading(null) listOf( charger, dataSource, @@ -122,10 +126,14 @@ class ChargepriceViewModel(application: Application, chargepriceApiKey: String) vehicleCompatibleConnectors, myTariffs, myTariffsAll ).forEach { - addSource(it) { + addSource(it.distinctUntilChanged()) { if (!batteryRangeSliderDragging.value!!) loadPrices() } } + observeForever { + // persist data in case fragment gets recreated + state["chargePrices"] = it + } } } diff --git a/app/src/main/java/net/vonforst/evmap/viewmodel/Utils.kt b/app/src/main/java/net/vonforst/evmap/viewmodel/Utils.kt index 7ba74692..5b7ea4e0 100644 --- a/app/src/main/java/net/vonforst/evmap/viewmodel/Utils.kt +++ b/app/src/main/java/net/vonforst/evmap/viewmodel/Utils.kt @@ -19,6 +19,16 @@ inline fun viewModelFactory(crossinline f: () -> VM) = override fun create(aClass: Class): T = f() as T } +@Suppress("UNCHECKED_CAST") +inline fun savedStateViewModelFactory(crossinline f: (SavedStateHandle) -> VM) = + object : AbstractSavedStateViewModelFactory() { + override fun create( + key: String, + modelClass: Class, + handle: SavedStateHandle + ) = f(handle) as T + } + enum class Status { SUCCESS, ERROR,