From 3488e89dbcad2c6a4312e07078ec313c4401957f Mon Sep 17 00:00:00 2001 From: Johan von Forstner Date: Sat, 16 May 2020 17:27:29 +0200 Subject: [PATCH] add link from favorites to detail view (fixes #8) --- app/src/main/java/net/vonforst/evmap/Utils.kt | 17 +++++ .../evmap/adapter/DataBindingAdapters.kt | 6 ++ .../evmap/fragment/FavoritesFragment.kt | 7 +- .../vonforst/evmap/fragment/MapFragment.kt | 72 ++++++++++++++----- app/src/main/res/layout/item_favorite.xml | 3 +- app/src/main/res/navigation/nav_graph.xml | 6 +- 6 files changed, 90 insertions(+), 21 deletions(-) create mode 100644 app/src/main/java/net/vonforst/evmap/Utils.kt diff --git a/app/src/main/java/net/vonforst/evmap/Utils.kt b/app/src/main/java/net/vonforst/evmap/Utils.kt new file mode 100644 index 00000000..ed5a4002 --- /dev/null +++ b/app/src/main/java/net/vonforst/evmap/Utils.kt @@ -0,0 +1,17 @@ +package net.vonforst.evmap + +import android.os.Bundle + +fun Bundle.optDouble(name: String): Double? { + if (!this.containsKey(name)) return null + + val dbl = this.getDouble(name, Double.NaN) + return if (dbl.isNaN()) null else dbl +} + +fun Bundle.optLong(name: String): Long? { + if (!this.containsKey(name)) return null + + val lng = this.getLong(name, Long.MIN_VALUE) + return if (lng == Long.MIN_VALUE) null else lng +} \ No newline at end of file diff --git a/app/src/main/java/net/vonforst/evmap/adapter/DataBindingAdapters.kt b/app/src/main/java/net/vonforst/evmap/adapter/DataBindingAdapters.kt index 6bedec7f..820cd707 100644 --- a/app/src/main/java/net/vonforst/evmap/adapter/DataBindingAdapters.kt +++ b/app/src/main/java/net/vonforst/evmap/adapter/DataBindingAdapters.kt @@ -28,6 +28,8 @@ interface Equatable { abstract class DataBindingAdapter() : ListAdapter>(DiffCallback()) { + var onClickListener: ((T) -> Unit)? = null + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val layoutInflater = LayoutInflater.from(parent.context) val binding = @@ -45,6 +47,10 @@ abstract class DataBindingAdapter() : open fun bind(holder: ViewHolder, item: T) { holder.binding.setVariable(BR.item, item) holder.binding.executePendingBindings() + holder.binding.root.setOnClickListener { + val listener = onClickListener ?: return@setOnClickListener + listener(item) + } } class DiffCallback : DiffUtil.ItemCallback() { diff --git a/app/src/main/java/net/vonforst/evmap/fragment/FavoritesFragment.kt b/app/src/main/java/net/vonforst/evmap/fragment/FavoritesFragment.kt index 43631a30..f9fae6d5 100644 --- a/app/src/main/java/net/vonforst/evmap/fragment/FavoritesFragment.kt +++ b/app/src/main/java/net/vonforst/evmap/fragment/FavoritesFragment.kt @@ -66,8 +66,13 @@ class FavoritesFragment : Fragment() { (requireActivity() as MapsActivity).appBarConfiguration ) + val favAdapter = FavoritesAdapter(vm).apply { + onClickListener = { + navController.navigate(R.id.action_favs_to_map, MapFragment.showCharger(it.charger)) + } + } binding.favsList.apply { - adapter = FavoritesAdapter(vm) + adapter = favAdapter layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) addItemDecoration( diff --git a/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt b/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt index 039f6218..85676741 100644 --- a/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt +++ b/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt @@ -42,9 +42,7 @@ import com.mahc.custombottomsheetbehavior.BottomSheetBehaviorGoogleMapsLike.STAT import com.mahc.custombottomsheetbehavior.BottomSheetBehaviorGoogleMapsLike.STATE_HIDDEN import com.mahc.custombottomsheetbehavior.MergedAppBarLayoutBehavior import kotlinx.android.synthetic.main.fragment_map.* -import net.vonforst.evmap.MapsActivity -import net.vonforst.evmap.R -import net.vonforst.evmap.REQUEST_LOCATION_PERMISSION +import net.vonforst.evmap.* import net.vonforst.evmap.adapter.ConnectorAdapter import net.vonforst.evmap.adapter.DetailAdapter import net.vonforst.evmap.adapter.GalleryAdapter @@ -56,12 +54,12 @@ import net.vonforst.evmap.ui.ChargerIconGenerator import net.vonforst.evmap.ui.ClusterIconGenerator import net.vonforst.evmap.ui.MarkerAnimator import net.vonforst.evmap.ui.getMarkerTint -import net.vonforst.evmap.viewmodel.GalleryViewModel -import net.vonforst.evmap.viewmodel.MapPosition -import net.vonforst.evmap.viewmodel.MapViewModel -import net.vonforst.evmap.viewmodel.viewModelFactory +import net.vonforst.evmap.viewmodel.* const val REQUEST_AUTOCOMPLETE = 2 +const val ARG_CHARGER_ID = "chargerId" +const val ARG_LAT = "lat" +const val ARG_LON = "lon" class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallback { private lateinit var binding: FragmentMapBinding @@ -369,23 +367,51 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac val position = vm.mapPosition.value - if (hasLocationPermission()) { - enableLocation(position == null, false) - } else if (position == null) { - // center the camera on Europe - val cameraUpdate = CameraUpdateFactory.newLatLngZoom(LatLng(50.113388, 9.252536), 3.5f) - map.moveCamera(cameraUpdate) - } + val lat = arguments?.optDouble(ARG_LAT) + val lon = arguments?.optDouble(ARG_LON) + var positionSet = false if (position != null) { val cameraUpdate = CameraUpdateFactory.newLatLngZoom(position.bounds.center, position.zoom) map.moveCamera(cameraUpdate) - } else { - vm.mapPosition.value = MapPosition( - map.projection.visibleRegion.latLngBounds, map.cameraPosition.zoom - ) + positionSet = true + } else if (lat != null && lon != null) { + // show given position + val cameraUpdate = CameraUpdateFactory.newLatLngZoom(LatLng(lat, lon), 16f) + map.moveCamera(cameraUpdate) + + // show charger detail after chargers were loaded + val chargerId = arguments?.optLong(ARG_CHARGER_ID) + vm.chargepoints.observe( + viewLifecycleOwner, + object : Observer>> { + override fun onChanged(res: Resource>) { + if (res.data == null) return + for (item in res.data) { + if (item is ChargeLocation && item.id == chargerId) { + vm.chargerSparse.value = item + vm.chargepoints.removeObserver(this) + } + } + } + }) + + positionSet = true } + if (hasLocationPermission()) { + enableLocation(!positionSet, false) + positionSet = true + } + if (!positionSet) { + // center the camera on Europe + val cameraUpdate = CameraUpdateFactory.newLatLngZoom(LatLng(50.113388, 9.252536), 3.5f) + map.moveCamera(cameraUpdate) + } + + vm.mapPosition.value = MapPosition( + map.projection.visibleRegion.latLngBounds, map.cameraPosition.zoom + ) } @SuppressLint("MissingPermission") @@ -526,4 +552,14 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac sharedElements[names[0]] = vh.itemView } } + + companion object { + fun showCharger(charger: ChargeLocation): Bundle { + return Bundle().apply { + putLong(ARG_CHARGER_ID, charger.id) + putDouble(ARG_LAT, charger.coordinates.lat) + putDouble(ARG_LON, charger.coordinates.lng) + } + } + } } \ No newline at end of file diff --git a/app/src/main/res/layout/item_favorite.xml b/app/src/main/res/layout/item_favorite.xml index 97acbf52..e596ed24 100644 --- a/app/src/main/res/layout/item_favorite.xml +++ b/app/src/main/res/layout/item_favorite.xml @@ -16,7 +16,8 @@ + android:padding="16dp" + android:background="?attr/selectableItemBackground"> + tools:layout="@layout/fragment_favorites"> + +