diff options
author | Iván Ávalos <avalos@disroot.org> | 2022-03-10 20:33:40 -0600 |
---|---|---|
committer | Iván Ávalos <avalos@disroot.org> | 2022-03-10 20:33:40 -0600 |
commit | 18987c3b31c2b8fe1a911297e8b104d583dd5c83 (patch) | |
tree | 43bc8d56c873fb1c6b4f56f3750f45a60519984d | |
parent | 9b8eee4362c368e682bfe18d5cef44d6b9d109bf (diff) | |
download | etbsa-trackermap-mobile-18987c3b31c2b8fe1a911297e8b104d583dd5c83.tar.gz etbsa-trackermap-mobile-18987c3b31c2b8fe1a911297e8b104d583dd5c83.tar.bz2 etbsa-trackermap-mobile-18987c3b31c2b8fe1a911297e8b104d583dd5c83.zip |
- Card on map now updates info when there is a change
- Huge device list performance improvements on search and updates
6 files changed, 78 insertions, 26 deletions
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesAdapter.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesAdapter.kt index 4cfd6b5..0fbf597 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesAdapter.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesAdapter.kt @@ -20,6 +20,7 @@ package mx.trackermap.TrackerMap.android.devices import android.view.LayoutInflater import android.view.ViewGroup import androidx.core.view.updateLayoutParams +import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import mx.trackermap.TrackerMap.android.R import mx.trackermap.TrackerMap.android.databinding.UnitItemBinding @@ -28,10 +29,18 @@ import mx.trackermap.TrackerMap.android.shared.UnitRenderData import mx.trackermap.TrackerMap.client.models.UnitInformation class DevicesAdapter( - private val units: List<UnitInformation>, + private val units: MutableList<UnitInformation>, private val actionCallback: ActionCallback? ) : RecyclerView.Adapter<DevicesAdapter.ViewHolder>() { + fun setData(units: List<UnitInformation>) { + val diffCallback = DevicesDiffCallback(this.units, units) + val diffResult = DiffUtil.calculateDiff(diffCallback) + this.units.clear() + this.units.addAll(units) + diffResult.dispatchUpdatesTo(this) + } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val binding = UnitItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesDiffCallback.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesDiffCallback.kt new file mode 100644 index 0000000..40e6e9c --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesDiffCallback.kt @@ -0,0 +1,20 @@ +package mx.trackermap.TrackerMap.android.devices + +import androidx.recyclerview.widget.DiffUtil +import mx.trackermap.TrackerMap.client.models.UnitInformation + +class DevicesDiffCallback( + private val oldList: List<UnitInformation>, + private val newList: List<UnitInformation> +): DiffUtil.Callback() { + override fun getOldListSize() = oldList.size + + override fun getNewListSize() = newList.size + + override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int) = + oldList[oldItemPosition].device.id == newList[newItemPosition].device.id + + override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int) = + (oldList[oldItemPosition].position?.id == newList[newItemPosition].position?.id) && newItemPosition != 0 + +}
\ No newline at end of file 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 ad93429..e5143cb 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 @@ -83,7 +83,7 @@ class DevicesFragment : Fragment() { context, LinearLayoutManager.VERTICAL, false ) - binding.devicesList.adapter = DevicesAdapter(emptyList(), null) + binding.devicesList.adapter = DevicesAdapter(mutableListOf(), this::itemAction) binding.infoLoading.root.visibility = View.VISIBLE } @@ -93,10 +93,7 @@ class DevicesFragment : Fragment() { unitsViewModel.units.observe(viewLifecycleOwner) { units -> Log.d("DevicesFragment", "Success $units") binding.infoLoading.root.visibility = View.GONE - binding.devicesList.swapAdapter( - DevicesAdapter(units, this::itemAction), - false - ) + (binding.devicesList.adapter as DevicesAdapter).setData(units) } } diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/UnitMapFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/UnitMapFragment.kt index e7e5ce0..5e2224b 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/UnitMapFragment.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/map/UnitMapFragment.kt @@ -85,7 +85,7 @@ class UnitMapFragment : Fragment() { childFragmentManager.commit { replace(R.id.unitsMap, mapFragment) } - mapFragment.setMarkerCallback(unitsViewModel::selectUnitWith) + mapFragment.setMarkerCallback(unitsViewModel::selectUnitWithPositionId) } private fun setupObservers() { @@ -132,14 +132,16 @@ class UnitMapFragment : Fragment() { ), binding.mapUnitCard.context, unit, this::itemAction ) - unitsViewModel.moveCamera( - UnitsViewModel.Camera( - point = Point2d( - unit.position!!.longitude!!, unit.position!!.latitude!! - ), - animated = true + if (selectedUnit.device.id != unitsViewModel.oldSelectedUnit.value?.device?.id) { + unitsViewModel.moveCamera( + UnitsViewModel.Camera( + point = Point2d( + unit.position!!.longitude!!, unit.position!!.latitude!! + ), + animated = true + ) ) - ) + } } } @@ -178,6 +180,7 @@ class UnitMapFragment : Fragment() { unitsViewModel.selectedUnit.removeObservers(viewLifecycleOwner) unitsViewModel.mapLayerType.removeObservers(viewLifecycleOwner) unitsViewModel.geofences.removeObservers(viewLifecycleOwner) + unitsViewModel.camera.removeObservers(viewLifecycleOwner) } private fun itemAction(unit: UnitInformation, action: UnitRenderData.Action) { 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 4371eed..09bedbb 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 @@ -128,9 +128,6 @@ class UnitsActivity : AppCompatActivity() { } private fun setupObservers() { - unitsViewModel.units.observe(this) { - Toast.makeText(this, getString(R.string.shared_loading), Toast.LENGTH_SHORT).show() - } unitsViewModel.unitsDisplayMode.observe(this) { displayMode -> binding.displayModeToggle.setImageResource( when (displayMode) { 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 ba29090..174d55e 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<List<UnitInformation>>() + private var _oldSelectedUnit = MutableLiveData<UnitInformation?>() private var _selectedUnit = MutableLiveData<UnitInformation?>() private var _mapLayerType = MutableLiveData<MapLayer.Type>() private var _geofences = MutableLiveData<Map<Int, Geofence>>() @@ -62,6 +63,7 @@ class UnitsViewModel( val searchQuery: LiveData<String> get() = _searchQuery val unitsDisplayMode: LiveData<UnitsDisplayMode> get() = _unitsDisplayMode val units: LiveData<List<UnitInformation>> get() = _units + val oldSelectedUnit: LiveData<UnitInformation?> get() = _oldSelectedUnit val selectedUnit: LiveData<UnitInformation?> get() = _selectedUnit val mapLayerType: LiveData<MapLayer.Type> get() = _mapLayerType val geofences: LiveData<Map<Int, Geofence>> get() = _geofences @@ -82,6 +84,7 @@ class UnitsViewModel( Log.d("UnitsViewModel", "Setup observers") unitsController.displayedUnitsFlow.collect { units -> this._units.value = units + updateSelectedUnit() } } @@ -91,22 +94,45 @@ class UnitsViewModel( } } - fun selectUnit(unit: UnitInformation) { - Log.d("UnitsViewModel", "Selecting unit ${unit.device.name}") + fun selectUnit(unit: UnitInformation?, switchToMap: Boolean = true) { + Log.d("UnitsViewModel", "Selecting unit ${unit?.device?.name}") + _oldSelectedUnit.postValue(_selectedUnit.value) _selectedUnit.postValue(unit) - setDisplayMode(UnitsDisplayMode.MAP) + if (unit != null && switchToMap) { + setDisplayMode(UnitsDisplayMode.MAP) + } } - fun selectUnitWith(positionId: Int?) { - if (positionId == null) { + fun selectUnitWithPositionId(id: Int?, switchToMap: Boolean = true) { + if (id == null) { Log.d("UnitsViewModel", "Deselecting unit") - _selectedUnit.postValue(null) + selectUnit(null, switchToMap = switchToMap) return } - Log.d("UnitsViewModel", "Selecting unit with position id: $positionId") - val unit = _units.value?.find { it.position?.id == positionId } - _selectedUnit.postValue(unit) + Log.d("UnitsViewModel", "Selecting unit with position id: $id") + val unit = _units.value?.find { it.position?.id == id } + selectUnit(unit, switchToMap = switchToMap) + } + + private fun selectUnitWithUnitId(id: Int?, switchToMap: Boolean = true) { + if (id == null) { + Log.d("UnitsViewModel", "Deselecting unit") + selectUnit(null, switchToMap = switchToMap) + return + } + + Log.d("UnitsViewModel", "Selecting unit with device id: $id") + val unit = _units.value?.find { it.device.id == id } + selectUnit(unit, switchToMap = switchToMap) + } + + private fun updateSelectedUnit() { + selectedUnit.value?.let { selected -> + Log.d("UnitsViewModel", "Updating selected unit with id: ${selected.device.id}") + selectUnitWithUnitId(selected.device.id, switchToMap = false) + } + } fun setDisplayMode(displayMode: UnitsDisplayMode) { |