mirror of
https://github.com/ev-map/EVMap.git
synced 2026-05-19 04:16:24 -04:00
implement my location button
This commit is contained in:
@@ -1,11 +1,17 @@
|
||||
package com.johan.evmap
|
||||
|
||||
import android.Manifest
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.databinding.Observable
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.gms.location.FusedLocationProviderClient
|
||||
import com.google.android.gms.location.LocationServices
|
||||
import com.google.android.gms.maps.CameraUpdateFactory
|
||||
import com.google.android.gms.maps.GoogleMap
|
||||
import com.google.android.gms.maps.OnMapReadyCallback
|
||||
@@ -24,13 +30,14 @@ import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
|
||||
const val REQUEST_LOCATION_PERMISSION = 1
|
||||
|
||||
class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
|
||||
private lateinit var binding: ActivityMapsBinding
|
||||
private lateinit var map: GoogleMap
|
||||
private lateinit var api: GoingElectricApi
|
||||
private lateinit var galleryAdapter: GalleryPagerAdapter
|
||||
private lateinit var fusedLocationClient: FusedLocationProviderClient
|
||||
private var chargepoints: List<ChargepointListItem> = emptyList()
|
||||
private var markers: Map<Marker, ChargeLocation> = emptyMap()
|
||||
private var clusterMarkers: List<Marker> = emptyList()
|
||||
@@ -38,6 +45,7 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = DataBindingUtil.setContentView(this, R.layout.activity_maps)
|
||||
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
|
||||
|
||||
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
|
||||
mapFragment.getMapAsync(this)
|
||||
@@ -78,16 +86,24 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
binding.fabLocate.setOnClickListener {
|
||||
if (!hasLocationPermission()) {
|
||||
ActivityCompat.requestPermissions(
|
||||
this,
|
||||
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
|
||||
REQUEST_LOCATION_PERMISSION
|
||||
)
|
||||
} else {
|
||||
enableLocation(true)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
override fun onMapReady(googleMap: GoogleMap) {
|
||||
map = googleMap
|
||||
|
||||
// Add a marker in Sydney and move the camera
|
||||
val sydney = LatLng(54.0, 9.0)
|
||||
map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 11f))
|
||||
|
||||
map.setOnCameraIdleListener {
|
||||
loadChargepoints()
|
||||
}
|
||||
@@ -108,8 +124,34 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
map.setOnMapClickListener {
|
||||
binding.charger = null
|
||||
}
|
||||
|
||||
if (hasLocationPermission()) {
|
||||
enableLocation(false)
|
||||
}
|
||||
}
|
||||
|
||||
private fun enableLocation(animate: Boolean) {
|
||||
map.isMyLocationEnabled = true
|
||||
binding.myLocationEnabled = true
|
||||
map.uiSettings.isMyLocationButtonEnabled = false
|
||||
fusedLocationClient.lastLocation.addOnSuccessListener { location ->
|
||||
if (location != null) {
|
||||
val latLng = LatLng(location.latitude, location.longitude)
|
||||
if (animate) {
|
||||
val camUpdate = CameraUpdateFactory.newLatLng(latLng)
|
||||
map.animateCamera(camUpdate)
|
||||
} else {
|
||||
val camUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 13f)
|
||||
map.moveCamera(camUpdate)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun hasLocationPermission() =
|
||||
ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) ==
|
||||
PackageManager.PERMISSION_GRANTED
|
||||
|
||||
private fun loadChargepoints() {
|
||||
val bounds = map.projection.visibleRegion.latLngBounds
|
||||
api.getChargepoints(
|
||||
@@ -197,4 +239,19 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<out String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
when (requestCode) {
|
||||
REQUEST_LOCATION_PERMISSION -> {
|
||||
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
|
||||
enableLocation(true)
|
||||
}
|
||||
}
|
||||
else -> super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,30 @@
|
||||
package com.johan.evmap.ui
|
||||
|
||||
import android.R
|
||||
import android.content.res.ColorStateList
|
||||
import android.util.TypedValue
|
||||
import android.view.View
|
||||
import androidx.databinding.BindingAdapter
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
|
||||
@BindingAdapter("app:goneUnless")
|
||||
|
||||
@BindingAdapter("goneUnless")
|
||||
fun goneUnless(view: View, visible: Boolean) {
|
||||
view.visibility = if (visible) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
@BindingAdapter("app:invisibleUnless")
|
||||
@BindingAdapter("invisibleUnless")
|
||||
fun invisibleUnless(view: View, visible: Boolean) {
|
||||
view.visibility = if (visible) View.VISIBLE else View.INVISIBLE
|
||||
}
|
||||
|
||||
@BindingAdapter("isFabActive")
|
||||
fun isFabActive(view: FloatingActionButton, isColored: Boolean) {
|
||||
val color = TypedValue()
|
||||
if (isColored) {
|
||||
view.context.theme.resolveAttribute(R.attr.colorAccent, color, true)
|
||||
} else {
|
||||
view.context.theme.resolveAttribute(R.attr.colorControlNormal, color, true)
|
||||
}
|
||||
view.imageTintList = ColorStateList.valueOf(color.data)
|
||||
}
|
||||
113
app/src/main/java/com/johan/evmap/ui/HideOnScrollFabBehavior.kt
Normal file
113
app/src/main/java/com/johan/evmap/ui/HideOnScrollFabBehavior.kt
Normal file
@@ -0,0 +1,113 @@
|
||||
package com.johan.evmap.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.mahc.custombottomsheetbehavior.BottomSheetBehaviorGoogleMapsLike
|
||||
|
||||
|
||||
class HideOnScrollFabBehavior(context: Context, attrs: AttributeSet) :
|
||||
FloatingActionButton.Behavior(context, attrs) {
|
||||
|
||||
override fun onStartNestedScroll(
|
||||
coordinatorLayout: CoordinatorLayout,
|
||||
child: FloatingActionButton,
|
||||
directTargetChild: View,
|
||||
target: View,
|
||||
axes: Int,
|
||||
type: Int
|
||||
): Boolean {
|
||||
Log.d("debug", "onStartNestedScroll")
|
||||
return axes == ViewCompat.SCROLL_AXIS_VERTICAL || super.onStartNestedScroll(
|
||||
coordinatorLayout,
|
||||
child,
|
||||
directTargetChild,
|
||||
target,
|
||||
axes,
|
||||
type
|
||||
)
|
||||
}
|
||||
|
||||
override fun layoutDependsOn(
|
||||
parent: CoordinatorLayout,
|
||||
child: FloatingActionButton,
|
||||
dependency: View
|
||||
): Boolean {
|
||||
if (dependency is NestedScrollView) {
|
||||
try {
|
||||
val behavior = BottomSheetBehaviorGoogleMapsLike.from<View>(dependency)
|
||||
behavior.addBottomSheetCallback(object :
|
||||
BottomSheetBehaviorGoogleMapsLike.BottomSheetCallback() {
|
||||
override fun onSlide(bottomSheet: View, slideOffset: Float) {
|
||||
|
||||
}
|
||||
|
||||
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||
onDependentViewChanged(parent, child, dependency)
|
||||
}
|
||||
})
|
||||
return true
|
||||
} catch (e: IllegalArgumentException) {
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onDependentViewChanged(
|
||||
parent: CoordinatorLayout,
|
||||
child: FloatingActionButton,
|
||||
dependency: View
|
||||
): Boolean {
|
||||
val behavior = BottomSheetBehaviorGoogleMapsLike.from<View>(dependency)
|
||||
Log.d("debug", "state: ${behavior.state}")
|
||||
when (behavior.state) {
|
||||
BottomSheetBehaviorGoogleMapsLike.STATE_SETTLING -> {
|
||||
|
||||
}
|
||||
BottomSheetBehaviorGoogleMapsLike.STATE_HIDDEN -> {
|
||||
child.show()
|
||||
}
|
||||
else -> {
|
||||
child.hide()
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onNestedScroll(
|
||||
coordinatorLayout: CoordinatorLayout,
|
||||
child: FloatingActionButton,
|
||||
target: View,
|
||||
dxConsumed: Int,
|
||||
dyConsumed: Int,
|
||||
dxUnconsumed: Int,
|
||||
dyUnconsumed: Int,
|
||||
type: Int,
|
||||
consumed: IntArray
|
||||
) {
|
||||
Log.d("debug", "onNestedScroll $dyConsumed")
|
||||
super.onNestedScroll(
|
||||
coordinatorLayout,
|
||||
child,
|
||||
target,
|
||||
dxConsumed,
|
||||
dyConsumed,
|
||||
dxUnconsumed,
|
||||
dyUnconsumed,
|
||||
type,
|
||||
consumed
|
||||
)
|
||||
if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
|
||||
// User scrolled down and the FAB is currently visible -> hide the FAB
|
||||
child.hide();
|
||||
} else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
|
||||
// User scrolled up and the FAB is currently not visible -> show the FAB
|
||||
child.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user