From 22d2b3ed3569925fc3835dd5b53c6aacde86278a Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Fri, 20 May 2022 22:27:59 -0500 Subject: [android] Improved search performance by limiting rate --- androidApp/build.gradle.kts | 4 +-- .../TrackerMap/android/units/UnitsActivity.kt | 38 +++++++++++++++++----- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/androidApp/build.gradle.kts b/androidApp/build.gradle.kts index 5bb488c..df33576 100644 --- a/androidApp/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -44,9 +44,9 @@ val googleImplementation by configurations dependencies { implementation(project(":shared")) - implementation("com.google.android.material:material:1.5.0") + implementation("com.google.android.material:material:1.6.0") implementation("androidx.appcompat:appcompat:1.4.1") - implementation("androidx.constraintlayout:constraintlayout:2.1.3") + implementation("androidx.constraintlayout:constraintlayout:2.1.4") implementation("com.squareup.okhttp3:okhttp:4.9.1") implementation("com.github.Zhuinden:live-event:1.2.0") implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1") diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt index 09bedbb..8a161c3 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt @@ -19,11 +19,13 @@ package mx.trackermap.TrackerMap.android.units import android.content.Context import android.content.Intent +import android.os.Build import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher import android.util.Log import android.view.View import android.view.inputmethod.InputMethodManager -import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.TooltipCompat import androidx.core.widget.doAfterTextChanged @@ -36,6 +38,7 @@ import mx.trackermap.TrackerMap.android.map.UnitMapFragment import mx.trackermap.TrackerMap.android.session.UserInformationActivity import mx.trackermap.TrackerMap.android.shared.Utils import org.koin.androidx.viewmodel.ext.android.viewModel +import java.util.* import kotlin.time.ExperimentalTime @DelicateCoroutinesApi @@ -100,13 +103,28 @@ class UnitsActivity : AppCompatActivity() { binding.mapLayerToggle.setOnClickListener { showLayersPopUp(it) } - binding.searchInput.doAfterTextChanged { - Log.d("UnitsActivity", "Search changed to ${it.toString()}") - if (unitsViewModel.unitsDisplayMode.value == UnitsViewModel.UnitsDisplayMode.MAP) { - unitsViewModel.setDisplayMode(UnitsViewModel.UnitsDisplayMode.LIST) + binding.searchInput.addTextChangedListener(object: TextWatcher { + override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} + override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} + + var timer = Timer() + val delay = 500L // milliseconds before doing search + + override fun afterTextChanged(p0: Editable?) { + timer.cancel() + timer = Timer() + timer.schedule(object: TimerTask() { + override fun run() { + Log.d("UnitsActivity", "Search changed to $p0") + if (unitsViewModel.unitsDisplayMode.value == UnitsViewModel.UnitsDisplayMode.MAP) { + unitsViewModel.setDisplayMode(UnitsViewModel.UnitsDisplayMode.LIST) + } + unitsViewModel.search(p0.toString()) + } + }, delay) } - unitsViewModel.search(it.toString()) - } + + }) binding.searchInputLayout.setEndIconOnClickListener { unfocusSearch(true) } @@ -119,7 +137,11 @@ class UnitsActivity : AppCompatActivity() { } private fun unfocusSearch(clearText: Boolean = false) { - val manager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + val manager = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + this.getSystemService(InputMethodManager::class.java) + } else { + this.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + } manager.hideSoftInputFromWindow(binding.searchInput.windowToken, 0) if (clearText) { binding.searchInput.text?.clear() -- cgit v1.2.3 From ec157026deea7b72ff233a20c0ed40fa548f75d6 Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Fri, 20 May 2022 23:21:37 -0500 Subject: - [shared] unitsFlow exposed to allow access to unfiltered units. - [android] Improved memory usage by using unitsFlow in map. - [ios] Not rewritten yet, filter won't work. --- .../TrackerMap/android/devices/DevicesFragment.kt | 2 +- .../TrackerMap/android/units/UnitsViewModel.kt | 20 +++++++++++++++++--- .../TrackerMap/controllers/UnitsController.kt | 2 +- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt index e5143cb..6e1b1c6 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt @@ -90,7 +90,7 @@ class DevicesFragment : Fragment() { @DelicateCoroutinesApi private fun setupObservers() { Log.d("DevicesFragment", "setupObservers()") - unitsViewModel.units.observe(viewLifecycleOwner) { units -> + unitsViewModel.displayedUnits.observe(viewLifecycleOwner) { units -> Log.d("DevicesFragment", "Success $units") binding.infoLoading.root.visibility = View.GONE (binding.devicesList.adapter as DevicesAdapter).setData(units) diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt index 174d55e..b537c0b 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsViewModel.kt @@ -54,6 +54,7 @@ class UnitsViewModel( private var _searchQuery = savedStateHandle.getLiveData("searchQuery", "") private var _unitsDisplayMode = MutableLiveData(UnitsDisplayMode.MAP) private var _units = MutableLiveData>() + private var _displayedUnits = MutableLiveData>() private var _oldSelectedUnit = MutableLiveData() private var _selectedUnit = MutableLiveData() private var _mapLayerType = MutableLiveData() @@ -63,6 +64,7 @@ class UnitsViewModel( val searchQuery: LiveData get() = _searchQuery val unitsDisplayMode: LiveData get() = _unitsDisplayMode val units: LiveData> get() = _units + val displayedUnits: LiveData> get() = _displayedUnits val oldSelectedUnit: LiveData get() = _oldSelectedUnit val selectedUnit: LiveData get() = _selectedUnit val mapLayerType: LiveData get() = _mapLayerType @@ -73,16 +75,27 @@ class UnitsViewModel( Log.d("UnitsViewModel", "Initializing Units View Model") unitsController.fetchUnits(viewModelScope) viewModelScope.launch { - setupObservers() + setupUnitsObserver() } + viewModelScope.launch { + setupDisplayedUnitsObserver() + } + viewModelScope.launch { setupGeofenceObserver() } } - private suspend fun setupObservers() { - Log.d("UnitsViewModel", "Setup observers") + private suspend fun setupUnitsObserver() { unitsController.displayedUnitsFlow.collect { units -> + Log.d("UnitsViewModel", "Collecting units") + this._displayedUnits.value = units + } + } + + private suspend fun setupDisplayedUnitsObserver() { + unitsController.unitsFlow.collect { units -> + Log.d("UnitsViewModel", "Collecting displayed units") this._units.value = units updateSelectedUnit() } @@ -90,6 +103,7 @@ class UnitsViewModel( private suspend fun setupGeofenceObserver() { geofenceController.geofencesFlow.collect { + Log.d("UnitsViewModel", "Collecting geofences") this._geofences.postValue(it) } } diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/UnitsController.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/UnitsController.kt index 8c36d50..529ca1b 100644 --- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/UnitsController.kt +++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/UnitsController.kt @@ -46,7 +46,7 @@ class UnitsController( } val displayedUnitsFlow = MutableStateFlow>(emptyList()) - private val unitsFlow = MutableStateFlow>(emptyList()) + val unitsFlow = MutableStateFlow>(emptyList()) private val queryFlow = MutableStateFlow("") init { -- cgit v1.2.3