From 1c4c5128fac5b1b6c8d9de29bd1ccf6262c7894b Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Thu, 30 Dec 2021 22:05:55 -0600 Subject: - ViewModel LiveData no longer externally mutable. - Observers in fragments now owned by viewLifecycleOwner. - Disabled center animation on MapFragment startup - Search filter now triggered automatically. - Case insensitive filter logic. --- .../TrackerMap/android/devices/DevicesFragment.kt | 3 +- .../TrackerMap/android/map/MapFragment.kt | 33 ++++++++++++---------- .../TrackerMap/android/units/UnitsActivity.kt | 16 +++-------- .../TrackerMap/android/units/UnitsViewModel.kt | 30 +++++++++++--------- 4 files changed, 40 insertions(+), 42 deletions(-) (limited to 'androidApp/src/main/java/mx/trackermap/TrackerMap') 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 eb8dcbc..bd3ab67 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 @@ -55,7 +55,8 @@ class DevicesFragment : Fragment() { @DelicateCoroutinesApi private fun setupObservers() { - unitsViewModel.units.observe(this) { units -> + Log.d("DevicesFragment", "setupObservers()") + unitsViewModel.units.observe(viewLifecycleOwner) { units -> Log.d("DevicesFragment", "Success $units") binding.devicesList.swapAdapter( DevicesAdapter(units, this::itemAction), diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt index 289cc2d..8dbd26c 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/MapFragment.kt @@ -1,19 +1,15 @@ package mx.trackermap.TrackerMap.android.map import android.graphics.BitmapFactory -import android.graphics.Point import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import com.mousebird.maply.* -import io.ktor.util.* import kotlinx.coroutines.DelicateCoroutinesApi import mx.trackermap.TrackerMap.android.R -import mx.trackermap.TrackerMap.android.databinding.MapFragmentBinding import mx.trackermap.TrackerMap.android.units.UnitsViewModel -import mx.trackermap.TrackerMap.client.models.UnitInformation import org.koin.androidx.viewmodel.ext.android.viewModel import java.io.File @@ -22,7 +18,7 @@ class MapFragment: GlobeMapFragment() { private val unitsViewModel: UnitsViewModel by viewModel() - private val markers = mutableListOf() + private val markers = mutableListOf>() override fun chooseDisplayType(): MapDisplayType { return MapDisplayType.Map @@ -59,7 +55,7 @@ class MapFragment: GlobeMapFragment() { val latitude = 23.191 * Math.PI / 180 val longitude = -100.36 * Math.PI / 180 val zoom = 0.4 - mapControl.animatePositionGeo(longitude, latitude, zoom, 1.0) + mapControl.setPositionGeo(longitude, latitude, zoom) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -70,13 +66,18 @@ class MapFragment: GlobeMapFragment() { @DelicateCoroutinesApi private fun setupObservers() { - unitsViewModel.units.observe(this) { units -> + Log.d("MapFragment", "setupObservers()") + unitsViewModel.units.observe(viewLifecycleOwner) { units -> + /* Remove all markers */ + markers.forEach { + mapControl.removeObject(it.second, ThreadMode.ThreadAny) + } + markers.clear() + + /* Reinsert markers from units */ units.forEach { unit -> unit.position?.let { position -> if (position.longitude != null && position.longitude != null) { - - /* Add marker */ - val markerInfo = MarkerInfo() val icon = BitmapFactory.decodeResource( activity!!.resources, @@ -105,23 +106,25 @@ class MapFragment: GlobeMapFragment() { else -> R.drawable.map_default } ) - val markerSize = Point2d(144.0, 144.0) val marker = ScreenMarker() + val markerSize = Point2d(144.0, 144.0) + marker.loc = Point2d.FromDegrees(position.longitude!!, position.latitude!!) marker.image = icon marker.size = markerSize marker.userObject = unit - markers.add(marker) - mapControl.addScreenMarker(marker, markerInfo, ThreadMode.ThreadAny) + /* Add marker to map */ + val markerInfo = MarkerInfo() + val componentObject = mapControl.addScreenMarker(marker, markerInfo, ThreadMode.ThreadAny) + markers.add(marker to componentObject) } } } } - unitsViewModel.selectedUnit.observe(this) { + unitsViewModel.selectedUnit.observe(viewLifecycleOwner) { it?.let { unit -> - Log.d("MapFragment", "Centering map on ${it.position?.latitude}, ${it.position?.longitude}") unit.position?.let { position -> val latitude = position.latitude!! * Math.PI / 180 val longitude = position.longitude!! * Math.PI / 180 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 ff8929e..8a6f699 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 @@ -20,9 +20,6 @@ class UnitsActivity : AppCompatActivity() { private val unitsViewModel: UnitsViewModel by viewModel() - private val mapFragment = MapFragment() - private val devicesFragment = DevicesFragment() - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -48,12 +45,7 @@ class UnitsActivity : AppCompatActivity() { } binding.searchInput.doAfterTextChanged { Log.d("UnitsActivity", "Search changed to ${it.toString()}") - unitsViewModel.searchQuery.value = it.toString() - } - binding.searchInput.setOnEditorActionListener { _, _, _ -> - Log.d("UnitsActivity", "Search key tapped") - unitsViewModel.search() - true + unitsViewModel.search(it.toString()) } } @@ -76,9 +68,9 @@ class UnitsActivity : AppCompatActivity() { val newFragment = when (displayMode) { - UnitsViewModel.UnitsDisplayMode.LIST -> devicesFragment - UnitsViewModel.UnitsDisplayMode.MAP -> mapFragment - else -> devicesFragment + UnitsViewModel.UnitsDisplayMode.LIST -> DevicesFragment() + UnitsViewModel.UnitsDisplayMode.MAP -> MapFragment() + else -> DevicesFragment() } supportFragmentManager.commit { replace(R.id.displayContainer, newFragment) 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 bb4efde..d8d7ea1 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 @@ -1,10 +1,7 @@ package mx.trackermap.TrackerMap.android.units import android.util.Log -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.SavedStateHandle -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope +import androidx.lifecycle.* import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch @@ -24,10 +21,15 @@ class UnitsViewModel( private val unitsController: UnitsController by inject() - var searchQuery = savedStateHandle.getLiveData("searchQuery", "") - var unitsDisplayMode = MutableLiveData(UnitsDisplayMode.LIST) - var units = MutableLiveData>() - var selectedUnit = MutableLiveData() + private var _searchQuery = savedStateHandle.getLiveData("searchQuery", "") + private var _unitsDisplayMode = MutableLiveData(UnitsDisplayMode.LIST) + private var _units = MutableLiveData>() + private var _selectedUnit = MutableLiveData() + + val searchQuery: LiveData get() = _searchQuery + val unitsDisplayMode: LiveData get() = _unitsDisplayMode + val units: LiveData> get() = _units + val selectedUnit: LiveData get() = _selectedUnit init { Log.d("UnitsViewModel", "Initializing Units View Model") @@ -39,19 +41,19 @@ class UnitsViewModel( private suspend fun setupObservers() { Log.d("UnitsViewModel", "Setup observers") unitsController.displayedUnitsFlow.collect { units -> - this.units.value = units + this._units.value = units } } fun selectUnit(unit: UnitInformation) { Log.d("UnitsViewModel", "Selecting unit ${unit.device.name}") - selectedUnit.postValue(unit) + _selectedUnit.postValue(unit) setDisplayMode(UnitsDisplayMode.MAP) } fun setDisplayMode(displayMode: UnitsDisplayMode) { Log.d("UnitsViewModel", "Setting Display mode to $displayMode") - unitsDisplayMode.postValue(displayMode) + _unitsDisplayMode.postValue(displayMode) } fun toggleDisplayMode() { @@ -62,10 +64,10 @@ class UnitsViewModel( } else { UnitsDisplayMode.MAP } - unitsDisplayMode.postValue(newDisplayMode) + _unitsDisplayMode.postValue(newDisplayMode) } - fun search() { - unitsController.search(searchQuery.value!!) + fun search(query: String) { + unitsController.search(query) } } \ No newline at end of file -- cgit v1.2.3