implement my location button

This commit is contained in:
Johan von Forstner
2020-03-19 22:43:56 +01:00
parent 567effed94
commit d4ee4a849a
8 changed files with 224 additions and 15 deletions

View File

@@ -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)
}
}
}

View File

@@ -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)
}

View 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();
}
}
}