@@ -7,28 +7,49 @@ import android.location.Location
7
7
import androidx.fragment.app.Fragment
8
8
9
9
import android.os.Bundle
10
+ import android.util.Log
10
11
import android.view.LayoutInflater
11
12
import android.view.View
12
13
import android.view.ViewGroup
14
+ import android.widget.LinearLayout
15
+ import android.widget.Toast
13
16
import androidx.core.content.ContextCompat.checkSelfPermission
14
17
import com.google.android.gms.location.FusedLocationProviderClient
15
18
import com.google.android.gms.location.LocationServices
19
+ import com.google.android.gms.common.api.Status
16
20
17
21
import com.google.android.gms.maps.CameraUpdateFactory
18
22
import com.google.android.gms.maps.GoogleMap
19
23
import com.google.android.gms.maps.OnMapReadyCallback
20
24
import com.google.android.gms.maps.SupportMapFragment
21
25
import com.google.android.gms.maps.model.LatLng
26
+ import com.google.android.gms.maps.model.Marker
22
27
import com.google.android.gms.maps.model.MarkerOptions
28
+ import com.google.android.libraries.places.api.Places
29
+ import com.google.android.libraries.places.api.model.Place
30
+ import com.google.android.libraries.places.api.model.RectangularBounds
31
+ import com.google.android.libraries.places.api.net.PlacesClient
32
+ import com.google.android.libraries.places.widget.AutocompleteSupportFragment
33
+ import com.google.android.libraries.places.widget.listener.PlaceSelectionListener
23
34
24
35
class MapsFragment : Fragment () {
25
36
26
37
private lateinit var map: GoogleMap
27
38
private lateinit var fusedLocationClient: FusedLocationProviderClient
28
39
private lateinit var lastLocation: Location
29
-
40
+ private lateinit var placesClient : PlacesClient
41
+ private lateinit var autocompleteLayout : LinearLayout
42
+ private lateinit var targetLatLng : LatLng
43
+ private lateinit var targetName : String
44
+ private lateinit var autocompleteFragment : AutocompleteSupportFragment
45
+ private var currentLatLng : LatLng ? = null
46
+ private var targetMarker : Marker ? = null
47
+
30
48
companion object {
31
49
private const val LOCATION_PERMISSION_REQUEST_CODE = 1
50
+ private const val ZOOM_VALUE = 14f
51
+ private const val PADDING_RATIO = 1.5
52
+ private const val FRAGMENT_TAG = " Mapfragment"
32
53
}
33
54
34
55
override fun onRequestPermissionsResult (requestCode : Int ,
@@ -51,27 +72,71 @@ class MapsFragment : Fragment() {
51
72
}
52
73
}
53
74
75
+ private fun initPlaces () {
76
+ context?.let { Places .initialize(it, getString(R .string.google_maps_key)) }
77
+ placesClient = context?.let { Places .createClient(it) }!!
78
+ }
79
+
80
+ private fun setPlacesSearchBias () {
81
+ // Search nearby result
82
+ currentLatLng?.let {
83
+ autocompleteFragment.setLocationBias(
84
+ RectangularBounds .newInstance(
85
+ LatLng (currentLatLng!! .latitude - 1 , currentLatLng!! .longitude - 1 ),
86
+ LatLng (currentLatLng!! .latitude + 1 , currentLatLng!! .longitude + 1 )
87
+ ))
88
+ }
89
+ }
90
+
54
91
private fun setUpMap () {
55
92
if (checkSelfPermission(context as Activity ,
56
93
Manifest .permission.ACCESS_FINE_LOCATION ) != PackageManager .PERMISSION_GRANTED ) {
57
94
requestPermissions(arrayOf(Manifest .permission.ACCESS_FINE_LOCATION ), LOCATION_PERMISSION_REQUEST_CODE )
58
95
return
59
96
}
60
97
98
+ // Add and adjust the position of MyLocation button.
61
99
map.isMyLocationEnabled = true
62
-
100
+ map.setPadding(0 , (PADDING_RATIO * autocompleteLayout.height).toInt(),0 ,0 )
101
+
63
102
fusedLocationClient.lastLocation.addOnSuccessListener(this .activity as Activity ) { location ->
64
103
// Got last known location. In some rare situations this can be null.
65
- if ( location != null ) {
104
+ location?. let {
66
105
lastLocation = location
67
- val currentLatLng = LatLng (location.latitude, location.longitude)
68
- map.animateCamera(CameraUpdateFactory .newLatLngZoom(currentLatLng, 12f ))
69
- map.addMarker(MarkerOptions ().position(currentLatLng).title(" My location" ))
70
- map.moveCamera(CameraUpdateFactory .newLatLng(currentLatLng))
106
+ currentLatLng = LatLng (location.latitude, location.longitude)
107
+ map.animateCamera(CameraUpdateFactory .newLatLngZoom(
108
+ currentLatLng,
109
+ ZOOM_VALUE
110
+ ))
111
+ map.addMarker(MarkerOptions ()
112
+ .position(currentLatLng!! )
113
+ .title(getString(R .string.my_location_title)))
114
+ map.moveCamera(CameraUpdateFactory .newLatLngZoom(
115
+ currentLatLng,
116
+ ZOOM_VALUE
117
+ ))
118
+ setPlacesSearchBias()
119
+ } ? : run {
120
+ Toast .makeText(context, getString(R .string.cannot_access_location), Toast .LENGTH_SHORT )
71
121
}
72
122
}
73
123
}
74
124
125
+ private fun setUpAutocomplete (autocompleteFragment : AutocompleteSupportFragment , mapFragment : SupportMapFragment ) {
126
+ autocompleteFragment.setPlaceFields(listOf (Place .Field .ID , Place .Field .NAME , Place .Field .LAT_LNG ))
127
+ autocompleteFragment.setOnPlaceSelectedListener(object : PlaceSelectionListener {
128
+ override fun onPlaceSelected (place : Place ) {
129
+ targetLatLng = place.latLng!!
130
+ targetName = place.name.toString()
131
+ mapFragment.getMapAsync(searchPlacesCallback)
132
+ }
133
+
134
+ override fun onError (status : Status ) {
135
+ Log .e(FRAGMENT_TAG , " An error occurred: $status " )
136
+ }
137
+ })
138
+ }
139
+
75
140
76
141
private val mapReadyCallback = OnMapReadyCallback { googleMap ->
77
142
/* *
@@ -88,6 +153,18 @@ class MapsFragment : Fragment() {
88
153
setUpMap()
89
154
}
90
155
156
+ private val searchPlacesCallback = OnMapReadyCallback { map ->
157
+ targetMarker?.remove()
158
+ map.moveCamera(CameraUpdateFactory .newLatLngZoom(
159
+ targetLatLng,
160
+ ZOOM_VALUE
161
+ ))
162
+ targetMarker = map.addMarker(MarkerOptions ()
163
+ .position(targetLatLng)
164
+ .title(targetName)
165
+ .draggable(true ))
166
+ }
167
+
91
168
override fun onCreateView (
92
169
inflater : LayoutInflater ,
93
170
container : ViewGroup ? ,
@@ -99,7 +176,13 @@ class MapsFragment : Fragment() {
99
176
100
177
override fun onViewCreated (view : View , savedInstanceState : Bundle ? ) {
101
178
super .onViewCreated(view, savedInstanceState)
102
- val mapFragment = childFragmentManager.findFragmentById(R .id.map) as SupportMapFragment ?
103
- mapFragment?.getMapAsync(mapReadyCallback)
179
+ initPlaces()
180
+
181
+ val mapFragment = childFragmentManager.findFragmentById(R .id.map_fragment) as SupportMapFragment
182
+ autocompleteFragment = childFragmentManager.findFragmentById(R .id.autocomplete_fragment) as AutocompleteSupportFragment
183
+ autocompleteLayout = view.findViewById(R .id.autocomplete_linearLayout)
184
+ mapFragment.getMapAsync(mapReadyCallback)
185
+
186
+ setUpAutocomplete(autocompleteFragment, mapFragment)
104
187
}
105
188
}
0 commit comments