Skip to content
This repository was archived by the owner on Jul 2, 2025. It is now read-only.

Commit b60386d

Browse files
authored
Merge pull request #472 from googlesamples/yang-mapview
mapview
2 parents b37af95 + 80e6432 commit b60386d

File tree

5 files changed

+119
-16
lines changed

5 files changed

+119
-16
lines changed

android/canonical/app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ dependencies {
3939
implementation 'com.google.android.material:material:1.1.0'
4040
implementation 'com.google.android.gms:play-services-maps:17.0.0'
4141
implementation 'com.google.android.gms:play-services-location:17.0.0'
42+
implementation 'com.google.android.libraries.places:places:2.3.0'
4243
implementation "android.arch.lifecycle:extensions:1.1.1"
4344
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
4445
kapt 'com.android.databinding:compiler:3.1.4'

android/canonical/app/src/main/java/com/google/samples/quickstart/canonical/MapsFragment.kt

Lines changed: 92 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,49 @@ import android.location.Location
77
import androidx.fragment.app.Fragment
88

99
import android.os.Bundle
10+
import android.util.Log
1011
import android.view.LayoutInflater
1112
import android.view.View
1213
import android.view.ViewGroup
14+
import android.widget.LinearLayout
15+
import android.widget.Toast
1316
import androidx.core.content.ContextCompat.checkSelfPermission
1417
import com.google.android.gms.location.FusedLocationProviderClient
1518
import com.google.android.gms.location.LocationServices
19+
import com.google.android.gms.common.api.Status
1620

1721
import com.google.android.gms.maps.CameraUpdateFactory
1822
import com.google.android.gms.maps.GoogleMap
1923
import com.google.android.gms.maps.OnMapReadyCallback
2024
import com.google.android.gms.maps.SupportMapFragment
2125
import com.google.android.gms.maps.model.LatLng
26+
import com.google.android.gms.maps.model.Marker
2227
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
2334

2435
class MapsFragment : Fragment() {
2536

2637
private lateinit var map: GoogleMap
2738
private lateinit var fusedLocationClient: FusedLocationProviderClient
2839
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+
3048
companion object {
3149
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"
3253
}
3354

3455
override fun onRequestPermissionsResult(requestCode: Int,
@@ -51,27 +72,71 @@ class MapsFragment : Fragment() {
5172
}
5273
}
5374

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+
5491
private fun setUpMap() {
5592
if (checkSelfPermission(context as Activity,
5693
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
5794
requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), LOCATION_PERMISSION_REQUEST_CODE)
5895
return
5996
}
6097

98+
// Add and adjust the position of MyLocation button.
6199
map.isMyLocationEnabled = true
62-
100+
map.setPadding(0, (PADDING_RATIO * autocompleteLayout.height).toInt(),0,0)
101+
63102
fusedLocationClient.lastLocation.addOnSuccessListener(this.activity as Activity) { location ->
64103
// Got last known location. In some rare situations this can be null.
65-
if (location != null) {
104+
location?.let {
66105
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)
71121
}
72122
}
73123
}
74124

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+
75140

76141
private val mapReadyCallback = OnMapReadyCallback { googleMap ->
77142
/**
@@ -88,6 +153,18 @@ class MapsFragment : Fragment() {
88153
setUpMap()
89154
}
90155

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+
91168
override fun onCreateView(
92169
inflater: LayoutInflater,
93170
container: ViewGroup?,
@@ -99,7 +176,13 @@ class MapsFragment : Fragment() {
99176

100177
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
101178
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)
104187
}
105188
}

android/canonical/app/src/main/res/layout/activity_main.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,4 @@
2424

2525
</FrameLayout>
2626

27-
2827
</androidx.constraintlayout.widget.ConstraintLayout>
Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,26 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
3-
xmlns:tools="http://schemas.android.com/tools"
4-
android:id="@+id/map"
5-
android:name="com.google.android.gms.maps.SupportMapFragment"
2+
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
63
android:layout_width="match_parent"
7-
android:layout_height="match_parent"
8-
tools:context=".MapsFragment" />
4+
android:layout_height="match_parent">
5+
6+
<fragment
7+
android:layout_width="match_parent"
8+
android:layout_height="match_parent"
9+
android:id="@+id/map_fragment"
10+
android:name="com.google.android.gms.maps.SupportMapFragment" />
11+
12+
<LinearLayout
13+
android:orientation="vertical"
14+
android:layout_margin="20dp"
15+
android:layout_width="match_parent"
16+
android:layout_height="wrap_content"
17+
android:id="@+id/autocomplete_linearLayout"
18+
android:background="@android:color/white">
19+
20+
<fragment
21+
android:layout_width="match_parent"
22+
android:layout_height="wrap_content"
23+
android:id="@+id/autocomplete_fragment"
24+
android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment" />
25+
</LinearLayout>
26+
</RelativeLayout>

android/canonical/app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@
88
<string name="start">Start Timer</string>
99
<string name="working">Started</string>
1010
<string name="stopped">Stopped</string>
11+
<string name="my_location_title">My location</string>
12+
<string name="cannot_access_location">Cannot access location now. Please Try later</string>
1113
</resources>

0 commit comments

Comments
 (0)