mirror of
https://github.com/googlemaps/android-samples.git
synced 2025-12-08 18:02:20 +00:00
commit
039bd04e6d
@ -27,6 +27,10 @@ dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
|
||||
implementation 'com.android.support:appcompat-v7:27.0.2'
|
||||
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||
// This dependency is needed to use RecyclerView, for the LiteListDemoActivity
|
||||
implementation "com.android.support:recyclerview-v7:27.0.2"
|
||||
// CardView is used in the LiteListDemoActivity
|
||||
implementation 'com.android.support:cardview-v7:27.0.2'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.1'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
|
||||
|
||||
17
ApiDemos/kotlin/app/src/debug/res/values/google_maps_api.xml
Normal file
17
ApiDemos/kotlin/app/src/debug/res/values/google_maps_api.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<resources>
|
||||
<!--
|
||||
TODO: Before you run your application, you need a Google Maps API key.
|
||||
|
||||
See this page for more information:
|
||||
https://developers.google.com/maps/documentation/android/start#get_an_android_certificate_and_the_google_maps_api_key
|
||||
|
||||
Once you have your key (it starts with "AIza"), replace the "google_maps_key"
|
||||
string in this file.
|
||||
|
||||
Note: This resource is used for the debug build target. Update this file if you just want to run
|
||||
the demo app.
|
||||
-->
|
||||
<string name="google_maps_key" translatable="false" templateMergeStrategy="preserve">
|
||||
ADD_YOUR_KEY_HERE
|
||||
</string>
|
||||
</resources>
|
||||
@ -38,14 +38,19 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".MarkerDemoActivity"/>
|
||||
<activity android:name=".LayersDemoActivity"/>
|
||||
<activity android:name=".PolygonDemoActivity"/>
|
||||
<activity android:name=".BasicMapDemoActivity" />
|
||||
<activity android:name=".CameraDemoActivity"/>
|
||||
<activity android:name=".CircleDemoActivity" />
|
||||
<activity android:name=".CloseInfoWindowDemoActivity" />
|
||||
<activity android:name=".LayersDemoActivity"/>
|
||||
<activity android:name=".LiteListDemoActivity" />
|
||||
<activity android:name=".MarkerDemoActivity"/>
|
||||
<activity android:name=".PolygonDemoActivity"/>
|
||||
<activity android:name=".PolylineDemoActivity"/>
|
||||
<activity android:name=".StreetViewPanoramaNavigationDemoActivity" />
|
||||
<activity android:name=".TagsDemoActivity"/>
|
||||
<activity android:name=".UiSettingsDemoActivity" />
|
||||
<activity android:name=".VisibleRegionDemoActivity"/>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.kotlindemos
|
||||
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
|
||||
import com.google.android.gms.maps.CameraUpdateFactory
|
||||
import com.google.android.gms.maps.GoogleMap
|
||||
import com.google.android.gms.maps.OnMapReadyCallback
|
||||
import com.google.android.gms.maps.SupportMapFragment
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.MarkerOptions
|
||||
|
||||
/**
|
||||
* This shows how to create a simple activity with a map and a marker on the map.
|
||||
*/
|
||||
class BasicMapDemoActivity :
|
||||
AppCompatActivity(),
|
||||
OnMapReadyCallback {
|
||||
|
||||
val SYDNEY = LatLng(-33.862, 151.21)
|
||||
val ZOOM_LEVEL = 13f
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_basic_map_demo)
|
||||
val mapFragment : SupportMapFragment? =
|
||||
supportFragmentManager.findFragmentById(R.id.map) as? SupportMapFragment
|
||||
mapFragment?.getMapAsync(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* This is where we can add markers or lines, add listeners or move the camera. In this case,
|
||||
* we just move the camera to Sydney and add a marker in Sydney.
|
||||
*/
|
||||
override fun onMapReady(googleMap: GoogleMap?) {
|
||||
googleMap ?: return
|
||||
with(googleMap) {
|
||||
moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, ZOOM_LEVEL))
|
||||
addMarker(MarkerOptions().position(SYDNEY))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.kotlindemos
|
||||
|
||||
import android.graphics.Color
|
||||
import android.graphics.Point
|
||||
import android.location.Location
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.CheckBox
|
||||
import android.widget.SeekBar
|
||||
import android.widget.Spinner
|
||||
|
||||
import com.google.android.gms.maps.CameraUpdateFactory
|
||||
import com.google.android.gms.maps.GoogleMap
|
||||
import com.google.android.gms.maps.OnMapReadyCallback
|
||||
import com.google.android.gms.maps.SupportMapFragment
|
||||
import com.google.android.gms.maps.model.BitmapDescriptorFactory
|
||||
import com.google.android.gms.maps.model.Circle
|
||||
import com.google.android.gms.maps.model.CircleOptions
|
||||
import com.google.android.gms.maps.model.Dash
|
||||
import com.google.android.gms.maps.model.Dot
|
||||
import com.google.android.gms.maps.model.Gap
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.Marker
|
||||
import com.google.android.gms.maps.model.MarkerOptions
|
||||
import com.google.android.gms.maps.model.PatternItem
|
||||
|
||||
import java.util.ArrayList
|
||||
import java.util.Arrays
|
||||
|
||||
/**
|
||||
* This shows how to draw circles on a map.
|
||||
*/
|
||||
class CircleDemoActivity :
|
||||
AppCompatActivity(),
|
||||
SeekBar.OnSeekBarChangeListener,
|
||||
AdapterView.OnItemSelectedListener,
|
||||
OnMapReadyCallback {
|
||||
|
||||
private val DEFAULT_RADIUS_METERS = 1000000.0
|
||||
|
||||
private val MAX_WIDTH_PX = 50
|
||||
private val MAX_HUE_DEGREE = 360
|
||||
|
||||
private val MAX_ALPHA = 255
|
||||
private val PATTERN_DASH_LENGTH = 100
|
||||
private val PATTERN_GAP_LENGTH = 200
|
||||
|
||||
private val sydney = LatLng(-33.87365, 151.20689)
|
||||
|
||||
private val dot = Dot()
|
||||
private val dash = Dash(PATTERN_DASH_LENGTH.toFloat())
|
||||
private val gap = Gap(PATTERN_GAP_LENGTH.toFloat())
|
||||
private val patternDotted = Arrays.asList(dot, gap)
|
||||
private val patternDashed = Arrays.asList(dash, gap)
|
||||
private val patternMixed = Arrays.asList(dot, gap, dot, dash, gap)
|
||||
|
||||
// These are the options for stroke patterns
|
||||
private val patterns: List<Pair<Int, List<PatternItem>?>> = listOf(
|
||||
Pair(R.string.pattern_solid, null),
|
||||
Pair(R.string.pattern_dashed, patternDashed),
|
||||
Pair(R.string.pattern_dotted, patternDotted),
|
||||
Pair(R.string.pattern_mixed, patternMixed)
|
||||
)
|
||||
|
||||
private lateinit var map: GoogleMap
|
||||
|
||||
private val circles = ArrayList<DraggableCircle>(1)
|
||||
|
||||
private var fillColorArgb : Int = 0
|
||||
private var strokeColorArgb: Int = 0
|
||||
|
||||
private lateinit var fillHueBar: SeekBar
|
||||
private lateinit var fillAlphaBar: SeekBar
|
||||
private lateinit var strokeWidthBar: SeekBar
|
||||
private lateinit var strokeHueBar: SeekBar
|
||||
private lateinit var strokeAlphaBar: SeekBar
|
||||
private lateinit var strokePatternSpinner: Spinner
|
||||
private lateinit var clickabilityCheckbox: CheckBox
|
||||
|
||||
/**
|
||||
* This class contains information about a circle, including its markers
|
||||
*/
|
||||
private inner class DraggableCircle(center: LatLng, private var radiusMeters: Double) {
|
||||
private val centerMarker: Marker = map.addMarker(MarkerOptions().apply {
|
||||
position(center)
|
||||
draggable(true)
|
||||
})
|
||||
|
||||
private val radiusMarker: Marker = map.addMarker(
|
||||
MarkerOptions().apply {
|
||||
position(center.getPointAtDistance(radiusMeters))
|
||||
icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
|
||||
draggable(true)
|
||||
})
|
||||
|
||||
private val circle: Circle = map.addCircle(
|
||||
CircleOptions().apply {
|
||||
center(center)
|
||||
radius(radiusMeters)
|
||||
strokeWidth(strokeWidthBar.progress.toFloat())
|
||||
strokeColor(strokeColorArgb)
|
||||
fillColor(fillColorArgb)
|
||||
clickable(clickabilityCheckbox.isChecked)
|
||||
strokePattern(getSelectedPattern(strokePatternSpinner.selectedItemPosition))
|
||||
})
|
||||
|
||||
fun onMarkerMoved(marker: Marker): Boolean {
|
||||
when (marker) {
|
||||
centerMarker -> {
|
||||
circle.center = marker.position
|
||||
radiusMarker.position = marker.position.getPointAtDistance(radiusMeters)
|
||||
}
|
||||
radiusMarker -> {
|
||||
radiusMeters = centerMarker.position.distanceFrom(radiusMarker.position)
|
||||
circle.radius = radiusMeters
|
||||
}
|
||||
else -> return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun onStyleChange() {
|
||||
// [circle] is treated as implicit this inside the with block
|
||||
with(circle) {
|
||||
strokeWidth = strokeWidthBar.progress.toFloat()
|
||||
strokeColor = strokeColorArgb
|
||||
fillColor = fillColorArgb
|
||||
}
|
||||
}
|
||||
|
||||
fun setStrokePattern(pattern: List<PatternItem>?) {
|
||||
circle.strokePattern = pattern
|
||||
}
|
||||
|
||||
fun setClickable(clickable: Boolean) {
|
||||
circle.isClickable = clickable
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_circle_demo)
|
||||
|
||||
// Set all the SeekBars
|
||||
fillHueBar = findViewById<SeekBar>(R.id.fillHueSeekBar).apply {
|
||||
max = MAX_HUE_DEGREE
|
||||
progress = MAX_HUE_DEGREE / 2
|
||||
}
|
||||
fillAlphaBar = findViewById<SeekBar>(R.id.fillAlphaSeekBar).apply {
|
||||
max = MAX_ALPHA
|
||||
progress = MAX_ALPHA / 2
|
||||
}
|
||||
strokeWidthBar = findViewById<SeekBar>(R.id.strokeWidthSeekBar).apply {
|
||||
max = MAX_WIDTH_PX
|
||||
progress = MAX_WIDTH_PX / 3
|
||||
}
|
||||
strokeHueBar = findViewById<SeekBar>(R.id.strokeHueSeekBar).apply {
|
||||
max = MAX_HUE_DEGREE
|
||||
progress = 0
|
||||
}
|
||||
strokeAlphaBar = findViewById<SeekBar>(R.id.strokeAlphaSeekBar).apply {
|
||||
max = MAX_ALPHA
|
||||
progress = MAX_ALPHA
|
||||
}
|
||||
|
||||
strokePatternSpinner = findViewById<Spinner>(R.id.strokePatternSpinner).apply {
|
||||
adapter = ArrayAdapter(this@CircleDemoActivity,
|
||||
android.R.layout.simple_spinner_item,
|
||||
getResourceStrings())
|
||||
}
|
||||
|
||||
clickabilityCheckbox = findViewById(R.id.toggleClickability)
|
||||
|
||||
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
|
||||
mapFragment.getMapAsync(this)
|
||||
}
|
||||
|
||||
/** Get all the strings of patterns and return them as Array. */
|
||||
private fun getResourceStrings() = (patterns).map { getString(it.first) }.toTypedArray()
|
||||
|
||||
/**
|
||||
* When the map is ready, move the camera to put the Circle in the middle of the screen,
|
||||
* create a circle in Sydney, and set the listeners for the map, circles, and SeekBars.
|
||||
*/
|
||||
override fun onMapReady(googleMap: GoogleMap?) {
|
||||
map = googleMap ?: return
|
||||
// we need to initialise map before creating a circle
|
||||
with(map) {
|
||||
moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 4.0f))
|
||||
setContentDescription(getString(R.string.circle_demo_details))
|
||||
setOnMapLongClickListener { point ->
|
||||
// We know the center, let's place the outline at a point 3/4 along the view.
|
||||
val view: View = supportFragmentManager.findFragmentById(R.id.map).view
|
||||
?: return@setOnMapLongClickListener
|
||||
val radiusLatLng = map.projection.fromScreenLocation(
|
||||
Point(view.height * 3 / 4, view.width * 3 / 4))
|
||||
// Create the circle.
|
||||
val newCircle = DraggableCircle(point, point.distanceFrom(radiusLatLng))
|
||||
circles.add(newCircle)
|
||||
}
|
||||
|
||||
setOnMarkerDragListener(object : GoogleMap.OnMarkerDragListener {
|
||||
override fun onMarkerDragStart(marker: Marker) {
|
||||
onMarkerMoved(marker)
|
||||
}
|
||||
|
||||
override fun onMarkerDragEnd(marker: Marker) {
|
||||
onMarkerMoved(marker)
|
||||
}
|
||||
|
||||
override fun onMarkerDrag(marker: Marker) {
|
||||
onMarkerMoved(marker)
|
||||
}
|
||||
})
|
||||
|
||||
// Flip the red, green and blue components of the circle's stroke color.
|
||||
setOnCircleClickListener { c -> c.strokeColor = c.strokeColor xor 0x00ffffff }
|
||||
}
|
||||
|
||||
fillColorArgb = Color.HSVToColor(fillAlphaBar.progress,
|
||||
floatArrayOf(fillHueBar.progress.toFloat(), 1f, 1f))
|
||||
strokeColorArgb = Color.HSVToColor(strokeAlphaBar.progress,
|
||||
floatArrayOf(strokeHueBar.progress.toFloat(), 1f, 1f))
|
||||
|
||||
val circle = DraggableCircle(sydney, DEFAULT_RADIUS_METERS)
|
||||
circles.add(circle)
|
||||
|
||||
// Set listeners for all the SeekBar
|
||||
fillHueBar.setOnSeekBarChangeListener(this)
|
||||
fillAlphaBar.setOnSeekBarChangeListener(this)
|
||||
|
||||
strokeWidthBar.setOnSeekBarChangeListener(this)
|
||||
strokeHueBar.setOnSeekBarChangeListener(this)
|
||||
strokeAlphaBar.setOnSeekBarChangeListener(this)
|
||||
|
||||
strokePatternSpinner.onItemSelectedListener = this
|
||||
}
|
||||
|
||||
private fun getSelectedPattern(pos: Int): List<PatternItem>? = patterns[pos].second
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>, view: View, pos: Int, id: Long) {
|
||||
if (parent.id == R.id.strokePatternSpinner) {
|
||||
circles.map { it.setStrokePattern(getSelectedPattern(pos)) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>) {
|
||||
// Don't do anything here.
|
||||
}
|
||||
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
||||
// Don't do anything here.
|
||||
}
|
||||
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar) {
|
||||
// Don't do anything here.
|
||||
}
|
||||
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
// Update the fillColorArgb if the SeekBars for it is changed, otherwise keep the old value
|
||||
fillColorArgb = when (seekBar) {
|
||||
fillHueBar -> Color.HSVToColor(Color.alpha(fillColorArgb),
|
||||
floatArrayOf(progress.toFloat(), 1f, 1f))
|
||||
fillAlphaBar -> Color.argb(progress, Color.red(fillColorArgb),
|
||||
Color.green(fillColorArgb), Color.blue(fillColorArgb))
|
||||
else -> fillColorArgb
|
||||
}
|
||||
|
||||
// Set the strokeColorArgb if the SeekBars for it is changed, otherwise keep the old value
|
||||
strokeColorArgb = when (seekBar) {
|
||||
strokeHueBar -> Color.HSVToColor(Color.alpha(strokeColorArgb),
|
||||
floatArrayOf(progress.toFloat(), 1f, 1f))
|
||||
strokeAlphaBar -> Color.argb(progress, Color.red(strokeColorArgb),
|
||||
Color.green(strokeColorArgb), Color.blue(strokeColorArgb))
|
||||
else -> strokeColorArgb
|
||||
}
|
||||
|
||||
// Apply the style change to all the circles.
|
||||
circles.map { it.onStyleChange() }
|
||||
}
|
||||
|
||||
private fun onMarkerMoved(marker: Marker) {
|
||||
circles.forEach { if (it.onMarkerMoved(marker)) return }
|
||||
}
|
||||
|
||||
/** Listener for the Clickable CheckBox, to set if all the circles can be click */
|
||||
fun toggleClickability(view: View) {
|
||||
circles.map { it.setClickable((view as CheckBox).isChecked) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension function to find the distance from this to another LatLng object
|
||||
*/
|
||||
private fun LatLng.distanceFrom(other: LatLng): Double {
|
||||
val result = FloatArray(1)
|
||||
Location.distanceBetween(latitude, longitude, other.latitude, other.longitude, result)
|
||||
return result[0].toDouble()
|
||||
}
|
||||
|
||||
private fun LatLng.getPointAtDistance(distance: Double): LatLng {
|
||||
val radiusOfEarth = 6371009.0
|
||||
val radiusAngle = (Math.toDegrees(distance / radiusOfEarth)
|
||||
/ Math.cos(Math.toRadians(latitude)))
|
||||
return LatLng(latitude, longitude + radiusAngle)
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.kotlindemos
|
||||
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import com.example.kotlindemos.OnMapAndViewReadyListener.OnGlobalLayoutAndMapReadyListener
|
||||
import com.google.android.gms.maps.CameraUpdateFactory
|
||||
import com.google.android.gms.maps.GoogleMap
|
||||
import com.google.android.gms.maps.SupportMapFragment
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.LatLngBounds
|
||||
import com.google.android.gms.maps.model.Marker
|
||||
import com.google.android.gms.maps.model.MarkerOptions
|
||||
|
||||
|
||||
/**
|
||||
* This shows how to close the info window when the currently selected marker is re-tapped.
|
||||
*/
|
||||
class CloseInfoWindowDemoActivity :
|
||||
AppCompatActivity(),
|
||||
OnGlobalLayoutAndMapReadyListener {
|
||||
|
||||
private lateinit var map: GoogleMap
|
||||
|
||||
/** Keeps track of the selected marker. It will be set to null if no marker is selected. */
|
||||
private var selectedMarker: Marker? = null
|
||||
|
||||
/**
|
||||
* If user tapped on the the marker which was already showing info window,
|
||||
* the showing info window will be closed. Otherwise will show a different window.
|
||||
*/
|
||||
private val markerClickListener = object : GoogleMap.OnMarkerClickListener {
|
||||
override fun onMarkerClick(marker: Marker?): Boolean {
|
||||
if (marker == selectedMarker) {
|
||||
selectedMarker = null
|
||||
// Return true to indicate we have consumed the event and that we do not
|
||||
// want the the default behavior to occur (which is for the camera to move
|
||||
// such that the marker is centered and for the marker's info window to open,
|
||||
// if it has one).
|
||||
return true
|
||||
}
|
||||
|
||||
selectedMarker = marker
|
||||
// Return false to indicate that we have not consumed the event and that
|
||||
// we wish for the default behavior to occur.
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_marker_close_info_window_on_retap_demo)
|
||||
|
||||
val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
|
||||
OnMapAndViewReadyListener(mapFragment, this)
|
||||
}
|
||||
|
||||
override fun onMapReady(googleMap: GoogleMap?) {
|
||||
// Return if googleMap was null
|
||||
map = googleMap ?: return
|
||||
|
||||
with(map) {
|
||||
uiSettings.isZoomControlsEnabled = false
|
||||
|
||||
setOnMarkerClickListener(markerClickListener)
|
||||
|
||||
// Set listener for map click event. Any showing info window closes
|
||||
// when the map is clicked. Clear the currently selected marker.
|
||||
setOnMapClickListener { selectedMarker = null }
|
||||
|
||||
setContentDescription(getString(R.string.close_info_window_demo_details))
|
||||
|
||||
// Add markers to different cities in Australia and include it in bounds
|
||||
val bounds = LatLngBounds.Builder()
|
||||
cities.map { city ->
|
||||
addMarker(MarkerOptions().apply {
|
||||
position(city.latLng)
|
||||
title(city.title)
|
||||
snippet(city.snippet)
|
||||
})
|
||||
bounds.include(city.latLng)
|
||||
}
|
||||
|
||||
moveCamera(CameraUpdateFactory.newLatLngBounds(bounds.build(), 50))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to contain information about a marker.
|
||||
*
|
||||
* @property latLng latitude and longitude of the marker
|
||||
* @property title a string containing the city name
|
||||
* @property snippet a string containing the population of the city
|
||||
*/
|
||||
class MarkerInfo(val latLng: LatLng, val title: String, val snippet: String)
|
||||
|
||||
private val cities = listOf(
|
||||
MarkerInfo(LatLng(-27.47093, 153.0235),
|
||||
"Brisbane", "Population: 2,074,200"),
|
||||
MarkerInfo(LatLng(-37.81319, 144.96298),
|
||||
"Melbourne", "Population: 4,137,400"),
|
||||
MarkerInfo(LatLng(-33.87365, 151.20689),
|
||||
"Sydney", "Population: 4,627,300"),
|
||||
MarkerInfo(LatLng(-34.92873, 138.59995),
|
||||
"Adelaide", "Population: 1,213,000"),
|
||||
MarkerInfo(LatLng(-31.952854, 115.857342),
|
||||
"Perth", "Population: 1,738,800")
|
||||
)
|
||||
}
|
||||
@ -22,18 +22,33 @@ package com.example.kotlindemos
|
||||
class DemoDetailsList {
|
||||
companion object {
|
||||
val DEMOS = listOf<DemoDetails>(
|
||||
DemoDetails(R.string.polygon_demo_label, R.string.polygon_demo_details,
|
||||
PolygonDemoActivity::class.java),
|
||||
DemoDetails(R.string.basic_demo_label, R.string.basic_demo_details,
|
||||
BasicMapDemoActivity::class.java),
|
||||
DemoDetails(R.string.camera_demo_label, R.string.camera_demo_description,
|
||||
CameraDemoActivity::class.java),
|
||||
DemoDetails(R.string.markers_demo_label, R.string.markers_demo_description,
|
||||
MarkerDemoActivity::class.java),
|
||||
DemoDetails(R.string.circle_demo_label, R.string.circle_demo_details,
|
||||
CircleDemoActivity::class.java),
|
||||
DemoDetails(R.string.close_info_window_demo_label,
|
||||
R.string.close_info_window_demo_details,
|
||||
CloseInfoWindowDemoActivity::class.java),
|
||||
DemoDetails(R.string.layers_demo_label, R.string.layers_demo_description,
|
||||
LayersDemoActivity::class.java),
|
||||
DemoDetails(R.string.lite_list_demo_label, R.string.lite_list_demo_details,
|
||||
LiteListDemoActivity::class.java),
|
||||
DemoDetails(R.string.markers_demo_label, R.string.markers_demo_description,
|
||||
MarkerDemoActivity::class.java),
|
||||
DemoDetails(R.string.polygon_demo_label, R.string.polygon_demo_details,
|
||||
PolygonDemoActivity::class.java),
|
||||
DemoDetails(R.string.polyline_demo_label, R.string.polyline_demo_description,
|
||||
PolylineDemoActivity::class.java),
|
||||
DemoDetails(
|
||||
R.string.street_view_panorama_navigation_demo_label,
|
||||
R.string.street_view_panorama_navigation_demo_details,
|
||||
StreetViewPanoramaNavigationDemoActivity::class.java),
|
||||
DemoDetails(R.string.tags_demo_label, R.string.tags_demo_details,
|
||||
TagsDemoActivity::class.java),
|
||||
DemoDetails(R.string.ui_settings_demo_label, R.string.ui_settings_demo_details,
|
||||
UiSettingsDemoActivity::class.java),
|
||||
DemoDetails(R.string.region_demo_label, R.string.region_demo_details,
|
||||
VisibleRegionDemoActivity::class.java)
|
||||
)
|
||||
|
||||
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.kotlindemos
|
||||
|
||||
import android.os.Bundle
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.support.v7.widget.GridLayoutManager
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import com.google.android.gms.maps.CameraUpdateFactory
|
||||
import com.google.android.gms.maps.GoogleMap
|
||||
import com.google.android.gms.maps.MapsInitializer
|
||||
import com.google.android.gms.maps.MapView
|
||||
import com.google.android.gms.maps.OnMapReadyCallback
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.MarkerOptions
|
||||
|
||||
/**
|
||||
* This shows to include a map in lite mode in a RecyclerView.
|
||||
* Note the use of the view holder pattern with the
|
||||
* [com.google.android.gms.maps.OnMapReadyCallback].
|
||||
*/
|
||||
class LiteListDemoActivity : AppCompatActivity() {
|
||||
|
||||
private val linearLayoutManager: LinearLayoutManager by lazy {
|
||||
LinearLayoutManager(this)
|
||||
}
|
||||
|
||||
private val gridLayoutManager: GridLayoutManager by lazy {
|
||||
GridLayoutManager(this, 2)
|
||||
}
|
||||
|
||||
private lateinit var recyclerView: RecyclerView
|
||||
private lateinit var mapAdapter: RecyclerView.Adapter<MapAdapter.ViewHolder>
|
||||
|
||||
/**
|
||||
* RecycleListener that completely clears the [com.google.android.gms.maps.GoogleMap]
|
||||
* attached to a row in the RecyclerView.
|
||||
* Sets the map type to [com.google.android.gms.maps.GoogleMap.MAP_TYPE_NONE] and clears
|
||||
* the map.
|
||||
*/
|
||||
private val recycleListener = RecyclerView.RecyclerListener { holder ->
|
||||
val mapHolder = holder as MapAdapter.ViewHolder
|
||||
mapHolder.clearView()
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_lite_list_demo)
|
||||
|
||||
mapAdapter = MapAdapter()
|
||||
|
||||
// Initialise the RecyclerView.
|
||||
recyclerView = findViewById<RecyclerView>(R.id.recycler_view).apply {
|
||||
setHasFixedSize(true)
|
||||
layoutManager = linearLayoutManager
|
||||
adapter = mapAdapter
|
||||
setRecyclerListener(recycleListener)
|
||||
}
|
||||
}
|
||||
|
||||
/** Create options menu to switch between the linear and grid layout managers. */
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
menuInflater.inflate(R.menu.lite_list_menu, menu)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||
recyclerView.layoutManager = when (item?.itemId) {
|
||||
R.id.layout_linear -> linearLayoutManager
|
||||
R.id.layout_grid -> gridLayoutManager
|
||||
else -> return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapter that displays a title and [com.google.android.gms.maps.MapView] for each item.
|
||||
* The layout is defined in `lite_list_demo_row.xml`. It contains a MapView
|
||||
* that is programatically initialised when onCreateViewHolder is called.
|
||||
*/
|
||||
inner class MapAdapter : RecyclerView.Adapter<MapAdapter.ViewHolder>() {
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
|
||||
holder?.bindView(position) ?: return
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val inflated = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.lite_list_demo_row, parent, false)
|
||||
return ViewHolder(inflated)
|
||||
}
|
||||
|
||||
override fun getItemCount() = listLocations.size
|
||||
|
||||
/** A view holder for the map and title. */
|
||||
inner class ViewHolder(view: View) :
|
||||
RecyclerView.ViewHolder(view),
|
||||
OnMapReadyCallback {
|
||||
|
||||
private val layout: View = view
|
||||
private val mapView: MapView = layout.findViewById(R.id.lite_listrow_map)
|
||||
private val title: TextView = layout.findViewById(R.id.lite_listrow_text)
|
||||
private lateinit var map: GoogleMap
|
||||
private lateinit var latLng: LatLng
|
||||
|
||||
/** Initialises the MapView by calling its lifecycle methods */
|
||||
init {
|
||||
with(mapView) {
|
||||
// Initialise the MapView
|
||||
onCreate(null)
|
||||
// Set the map ready callback to receive the GoogleMap object
|
||||
getMapAsync(this@ViewHolder)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setMapLocation() {
|
||||
if (!::map.isInitialized) return
|
||||
with(map) {
|
||||
moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 13f))
|
||||
addMarker(MarkerOptions().position(latLng))
|
||||
mapType = GoogleMap.MAP_TYPE_NORMAL
|
||||
setOnMapClickListener {
|
||||
Toast.makeText(this@LiteListDemoActivity, "Clicked on ${title.text}",
|
||||
Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMapReady(googleMap: GoogleMap?) {
|
||||
MapsInitializer.initialize(applicationContext)
|
||||
// If map is not initialised properly
|
||||
map = googleMap ?: return
|
||||
setMapLocation()
|
||||
}
|
||||
|
||||
/** This function is called when the RecyclerView wants to bind the ViewHolder. */
|
||||
fun bindView(position: Int) {
|
||||
listLocations[position].let {
|
||||
latLng = it.second
|
||||
mapView.tag = this
|
||||
title.text = it.first
|
||||
// We need to call setMapLocation from here because RecyclerView might use the
|
||||
// previously loaded maps
|
||||
setMapLocation()
|
||||
}
|
||||
}
|
||||
|
||||
/** This function is called by the recycleListener, when we need to clear the map. */
|
||||
fun clearView() {
|
||||
with(map) {
|
||||
// Clear the map and free up resources by changing the map type to none
|
||||
clear()
|
||||
mapType = GoogleMap.MAP_TYPE_NONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** A list of locations of to show in the RecyclerView */
|
||||
private val listLocations: List<Pair<String, LatLng>> = listOf(
|
||||
Pair("Cape Town", LatLng(-33.920455, 18.466941)),
|
||||
Pair("Beijing", LatLng(39.937795, 116.387224)),
|
||||
Pair("Bern", LatLng(46.948020, 7.448206)),
|
||||
Pair("Breda", LatLng(51.589256, 4.774396)),
|
||||
Pair("Brussels", LatLng(50.854509, 4.376678)),
|
||||
Pair("Copenhagen", LatLng(55.679423, 12.577114)),
|
||||
Pair("Hannover", LatLng(52.372026, 9.735672)),
|
||||
Pair("Helsinki", LatLng(60.169653, 24.939480)),
|
||||
Pair("Hong Kong", LatLng(22.325862, 114.165532)),
|
||||
Pair("Istanbul", LatLng(41.034435, 28.977556)),
|
||||
Pair("Johannesburg", LatLng(-26.202886, 28.039753)),
|
||||
Pair("Lisbon", LatLng(38.707163, -9.135517)),
|
||||
Pair("London", LatLng(51.500208, -0.126729)),
|
||||
Pair("Madrid", LatLng(40.420006, -3.709924)),
|
||||
Pair("Mexico City", LatLng(19.427050, -99.127571)),
|
||||
Pair("Moscow", LatLng(55.750449, 37.621136)),
|
||||
Pair("New York", LatLng(40.750580, -73.993584)),
|
||||
Pair("Oslo", LatLng(59.910761, 10.749092)),
|
||||
Pair("Paris", LatLng(48.859972, 2.340260)),
|
||||
Pair("Prague", LatLng(50.087811, 14.420460)),
|
||||
Pair("Rio de Janeiro", LatLng(-22.90187, -43.232437)),
|
||||
Pair("Rome", LatLng(41.889998, 12.500162)),
|
||||
Pair("Sao Paolo", LatLng(-22.863878, -43.244097)),
|
||||
Pair("Seoul", LatLng(37.560908, 126.987705)),
|
||||
Pair("Stockholm", LatLng(59.330650, 18.067360)),
|
||||
Pair("Sydney", LatLng(-33.873651, 151.2068896)),
|
||||
Pair("Taipei", LatLng(25.022112, 121.478019)),
|
||||
Pair("Tokyo", LatLng(35.670267, 139.769955)),
|
||||
Pair("Tulsa Oklahoma", LatLng(36.149777, -95.993398)),
|
||||
Pair("Vaduz", LatLng(47.141076, 9.521482)),
|
||||
Pair("Vienna", LatLng(48.209206, 16.372778)),
|
||||
Pair("Warsaw", LatLng(52.235474, 21.004057)),
|
||||
Pair("Wellington", LatLng(-41.286480, 174.776217)),
|
||||
Pair("Winnipeg", LatLng(49.875832, -97.150726))
|
||||
)
|
||||
}
|
||||
@ -61,8 +61,8 @@ class MainActivity : AppCompatActivity(), AdapterView.OnItemClickListener {
|
||||
class CustomArrayAdapter(context: Context, demos: List<DemoDetails>) :
|
||||
ArrayAdapter<DemoDetails>(context, R.id.title, demos) {
|
||||
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup) : View {
|
||||
val demo : DemoDetails = getItem(position)
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||
val demo: DemoDetails = getItem(position)
|
||||
return (convertView as? FeatureView ?: FeatureView(context)).apply {
|
||||
setTitleId(demo.titleId)
|
||||
setDescriptionId(demo.descriptionId)
|
||||
|
||||
@ -73,6 +73,7 @@ class OnMapAndViewReadyListener(
|
||||
}
|
||||
|
||||
// We use the new method when supported
|
||||
@Suppress("DEPRECATION")
|
||||
@SuppressLint("NewApi") // We check which build version we are using.
|
||||
override fun onGlobalLayout() {
|
||||
// Remove our listener.
|
||||
|
||||
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.kotlindemos
|
||||
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.SeekBar
|
||||
import android.widget.Toast
|
||||
import com.google.android.gms.maps.StreetViewPanorama
|
||||
import com.google.android.gms.maps.SupportStreetViewPanoramaFragment
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.StreetViewPanoramaCamera
|
||||
import com.google.android.gms.maps.model.StreetViewPanoramaLink
|
||||
|
||||
/**
|
||||
* This shows how to create an activity with access to all the options in Panorama
|
||||
* which can be adjusted dynamically.
|
||||
*/
|
||||
class StreetViewPanoramaNavigationDemoActivity : AppCompatActivity() {
|
||||
|
||||
// George St, Sydney
|
||||
private val sydney = LatLng(-33.87365, 151.20689)
|
||||
// Cole St, San Francisco
|
||||
private val sanFrancisco = LatLng(37.769263, -122.450727)
|
||||
// Santorini, Greece using the Pano ID of the location instead of a LatLng object
|
||||
private val santoriniPanoId = "WddsUw1geEoAAAQIt9RnsQ"
|
||||
// LatLng with no panorama
|
||||
private val invalid = LatLng(-45.125783, 151.276417)
|
||||
|
||||
// The amount in degrees by which to scroll the camera
|
||||
private val PAN_BY_DEGREES = 30
|
||||
// The amount of zoom
|
||||
private val ZOOM_BY = 0.5f
|
||||
|
||||
private lateinit var streetViewPanorama: StreetViewPanorama
|
||||
private lateinit var customDurationBar: SeekBar
|
||||
|
||||
private val duration: Long
|
||||
get() = customDurationBar.progress.toLong()
|
||||
|
||||
override fun onCreate(savedInstanceState:Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_street_view_panorama_navigation_demo)
|
||||
|
||||
val streetViewPanoramaFragment = supportFragmentManager
|
||||
.findFragmentById(R.id.streetviewpanorama) as SupportStreetViewPanoramaFragment
|
||||
streetViewPanoramaFragment.getStreetViewPanoramaAsync { panorama ->
|
||||
streetViewPanorama = panorama
|
||||
// Only set the panorama to sydney on startup (when no panoramas have been
|
||||
// loaded which is when the savedInstanceState is null).
|
||||
if (savedInstanceState == null) {
|
||||
streetViewPanorama.setPosition(sydney)
|
||||
}
|
||||
}
|
||||
|
||||
customDurationBar = findViewById(R.id.duration_bar)
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the map is ready, the executes the provided lamdba function
|
||||
*
|
||||
* @param stuffToDo the code to be executed if [streetViewPanorama] is ready
|
||||
*/
|
||||
private fun checkReadyThen(stuffToDo : () -> Unit) {
|
||||
if (!::streetViewPanorama.isInitialized) {
|
||||
Toast.makeText(this, R.string.map_not_ready, Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
stuffToDo()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the Go To Location button is pressed
|
||||
*/
|
||||
fun onGoToLocation(view: View) {
|
||||
when (view.id) {
|
||||
R.id.sydney -> streetViewPanorama.setPosition(sydney)
|
||||
R.id.sanfrancisco -> streetViewPanorama.setPosition(sanFrancisco)
|
||||
R.id.santorini -> streetViewPanorama.setPosition(santoriniPanoId)
|
||||
R.id.invalid -> streetViewPanorama.setPosition(invalid)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called from the listeners, and builds the street view panorama with the
|
||||
* specified arguments.
|
||||
*/
|
||||
private fun updateStreetViewPanorama(zoom: Float, tilt: Float, bearing: Float) {
|
||||
streetViewPanorama.animateTo(StreetViewPanoramaCamera.Builder().apply {
|
||||
zoom(zoom)
|
||||
tilt(tilt)
|
||||
bearing(bearing)
|
||||
} .build(), duration)
|
||||
}
|
||||
|
||||
fun onButtonClicked(view: View) {
|
||||
checkReadyThen {
|
||||
with(streetViewPanorama.panoramaCamera) {
|
||||
when (view.id) {
|
||||
R.id.zoom_in -> updateStreetViewPanorama(zoom + ZOOM_BY, tilt, bearing)
|
||||
R.id.zoom_out -> updateStreetViewPanorama(zoom - ZOOM_BY, tilt, bearing)
|
||||
R.id.pan_left -> updateStreetViewPanorama(zoom, tilt, bearing - PAN_BY_DEGREES)
|
||||
R.id.pan_right -> updateStreetViewPanorama(zoom, tilt, bearing + PAN_BY_DEGREES)
|
||||
R.id.pan_up -> {
|
||||
var newTilt = tilt + PAN_BY_DEGREES
|
||||
if (newTilt > 90) newTilt = 90f
|
||||
updateStreetViewPanorama(zoom, newTilt, bearing)
|
||||
}
|
||||
R.id.pan_down -> {
|
||||
var newTilt = tilt - PAN_BY_DEGREES
|
||||
if (newTilt < -90) newTilt = -90f
|
||||
updateStreetViewPanorama(zoom, newTilt, bearing)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onRequestPosition(view: View) {
|
||||
checkReadyThen {
|
||||
streetViewPanorama.location?.let {
|
||||
Toast.makeText(view.context, streetViewPanorama.location.position.toString(),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
fun onMovePosition(view: View) {
|
||||
val location = streetViewPanorama.location
|
||||
val camera = streetViewPanorama.panoramaCamera
|
||||
location?.links?.let {
|
||||
val link = location.links.findClosestLinkToBearing(camera.bearing)
|
||||
streetViewPanorama.setPosition(link.panoId)
|
||||
}
|
||||
}
|
||||
|
||||
/** Extension function to find the closest link from a point. */
|
||||
private fun Array<StreetViewPanoramaLink>.findClosestLinkToBearing(
|
||||
bearing: Float
|
||||
): StreetViewPanoramaLink {
|
||||
|
||||
// Find the difference between angle a and b as a value between 0 and 180.
|
||||
val findNormalizedDifference = fun (a: Float, b: Float): Float {
|
||||
val diff = a - b
|
||||
val normalizedDiff = diff - (360 * Math.floor((diff / 360.0f).toDouble())).toFloat()
|
||||
return if ((normalizedDiff < 180.0f)) normalizedDiff else 360.0f - normalizedDiff
|
||||
}
|
||||
|
||||
var minBearingDiff = 360f
|
||||
var closestLink = this[0]
|
||||
for (link in this) {
|
||||
if (minBearingDiff > findNormalizedDifference(bearing, link.bearing)) {
|
||||
minBearingDiff = findNormalizedDifference(bearing, link.bearing)
|
||||
closestLink = link
|
||||
}
|
||||
}
|
||||
return closestLink
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2018 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.kotlindemos
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.widget.CheckBox
|
||||
import com.google.android.gms.maps.GoogleMap
|
||||
import com.google.android.gms.maps.OnMapReadyCallback
|
||||
import com.google.android.gms.maps.SupportMapFragment
|
||||
import pub.devrel.easypermissions.AfterPermissionGranted
|
||||
import pub.devrel.easypermissions.EasyPermissions
|
||||
|
||||
const val REQUEST_CODE_LOCATION = 123
|
||||
|
||||
class UiSettingsDemoActivity :
|
||||
AppCompatActivity(),
|
||||
OnMapReadyCallback {
|
||||
|
||||
private lateinit var map: GoogleMap
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_ui_settings_demo)
|
||||
val mapFragment: SupportMapFragment =
|
||||
supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
|
||||
mapFragment.getMapAsync(this)
|
||||
}
|
||||
|
||||
override fun onMapReady(googleMap: GoogleMap?) {
|
||||
// Return early if map is not initialised properly
|
||||
map = googleMap ?: return
|
||||
enableMyLocation()
|
||||
// Set all the settings of the map to match the current state of the checkboxes
|
||||
with(map.uiSettings) {
|
||||
isZoomControlsEnabled = isChecked(R.id.zoom_button)
|
||||
isCompassEnabled = isChecked(R.id.compass_button)
|
||||
isMyLocationButtonEnabled = isChecked(R.id.myloc_button)
|
||||
isIndoorLevelPickerEnabled = isChecked(R.id.level_button)
|
||||
isMapToolbarEnabled = isChecked(R.id.maptoolbar_button)
|
||||
isZoomGesturesEnabled = isChecked(R.id.zoomgest_button)
|
||||
isScrollGesturesEnabled = isChecked(R.id.scrollgest_button)
|
||||
isTiltGesturesEnabled = isChecked(R.id.tiltgest_button)
|
||||
isRotateGesturesEnabled = isChecked(R.id.rotategest_button)
|
||||
}
|
||||
}
|
||||
|
||||
/** On click listener for checkboxes */
|
||||
fun onClick(view: View) {
|
||||
if (view !is CheckBox) {
|
||||
return
|
||||
}
|
||||
val isChecked: Boolean = view.isChecked
|
||||
with(map.uiSettings) {
|
||||
when (view.id) {
|
||||
R.id.zoom_button -> isZoomControlsEnabled = isChecked
|
||||
R.id.compass_button -> isCompassEnabled = isChecked
|
||||
R.id.myloc_button -> isMyLocationButtonEnabled = isChecked
|
||||
R.id.level_button -> isIndoorLevelPickerEnabled = isChecked
|
||||
R.id.maptoolbar_button -> isMapToolbarEnabled = isChecked
|
||||
R.id.zoomgest_button -> isZoomGesturesEnabled = isChecked
|
||||
R.id.scrollgest_button -> isScrollGesturesEnabled = isChecked
|
||||
R.id.tiltgest_button -> isTiltGesturesEnabled = isChecked
|
||||
R.id.rotategest_button -> isRotateGesturesEnabled = isChecked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns whether the checkbox with the given id is checked */
|
||||
private fun isChecked(id: Int) = findViewById<CheckBox>(id)?.isChecked ?: false
|
||||
|
||||
/** Override the onRequestPermissionResult to use EasyPermissions */
|
||||
override fun onRequestPermissionsResult(
|
||||
requestCode: Int,
|
||||
permissions: Array<out String>,
|
||||
grantResults: IntArray
|
||||
) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* enableMyLocation() will enable the location of the map if the user has given permission
|
||||
* for the app to access their device location.
|
||||
* Android Studio requires an explicit check before setting map.isMyLocationEnabled to true
|
||||
* but we are using EasyPermissions to handle it so we can suppress the "MissingPermission"
|
||||
* check.
|
||||
*/
|
||||
@SuppressLint("MissingPermission")
|
||||
@AfterPermissionGranted(REQUEST_CODE_LOCATION)
|
||||
private fun enableMyLocation() {
|
||||
if (hasLocationPermission()) {
|
||||
map.isMyLocationEnabled = true
|
||||
} else {
|
||||
EasyPermissions.requestPermissions(this, getString(R.string.location),
|
||||
REQUEST_CODE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun hasLocationPermission(): Boolean {
|
||||
return EasyPermissions.hasPermissions(this, Manifest.permission.ACCESS_FINE_LOCATION)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/map"
|
||||
android:name="com.google.android.gms.maps.SupportMapFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.example.kotlindemos.BasicMapDemoActivity">
|
||||
|
||||
</fragment>
|
||||
109
ApiDemos/kotlin/app/src/main/res/layout/activity_circle_demo.xml
Normal file
109
ApiDemos/kotlin/app/src/main/res/layout/activity_circle_demo.xml
Normal file
@ -0,0 +1,109 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/properties_circle" />
|
||||
|
||||
<TableLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:stretchColumns="1">
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
<TextView android:text="@string/fill_hue" />
|
||||
<SeekBar android:id="@+id/fillHueSeekBar" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
<TextView android:text="@string/fill_alpha" />
|
||||
<SeekBar android:id="@+id/fillAlphaSeekBar" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
<TextView android:text="@string/stroke_width" />
|
||||
<SeekBar android:id="@+id/strokeWidthSeekBar" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
<TextView android:text="@string/stroke_hue" />
|
||||
<SeekBar android:id="@+id/strokeHueSeekBar" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
<TextView android:text="@string/stroke_alpha" />
|
||||
<SeekBar android:id="@+id/strokeAlphaSeekBar" />
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
<TextView
|
||||
android:text="@string/stroke_pattern"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
<Spinner
|
||||
android:id="@+id/strokePatternSpinner"
|
||||
android:spinnerMode="dropdown"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</TableRow>
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical">
|
||||
<CheckBox
|
||||
android:id="@+id/toggleClickability"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:onClick="toggleClickability"
|
||||
android:text="@string/clickable"/>
|
||||
</TableRow>
|
||||
|
||||
</TableLayout>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/map"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
class="com.google.android.gms.maps.SupportMapFragment"/>
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:scrollbars="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android" />
|
||||
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
<fragment
|
||||
android:id="@+id/map"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
class="com.google.android.gms.maps.SupportMapFragment"/>
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,191 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<Button
|
||||
android:id="@+id/get_position"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onRequestPosition"
|
||||
android:text="@string/request_position" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/move_position"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onMovePosition"
|
||||
android:text="@string/walk_panorama" />
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_weight="1">
|
||||
|
||||
<Button
|
||||
android:id="@+id/pan_left"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="48dp"
|
||||
android:onClick="onButtonClicked"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="@string/left_arrow"
|
||||
android:layout_alignParentStart="true" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/pan_up"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="48dp"
|
||||
android:onClick="onButtonClicked"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_toRightOf="@id/pan_left"
|
||||
android:text="@string/up_arrow"
|
||||
android:layout_toEndOf="@id/pan_left" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/pan_down"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="48dp"
|
||||
android:onClick="onButtonClicked"
|
||||
android:layout_below="@id/pan_up"
|
||||
android:layout_toRightOf="@id/pan_left"
|
||||
android:text="@string/down_arrow"
|
||||
android:layout_toEndOf="@id/pan_left" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/pan_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="48dp"
|
||||
android:onClick="onButtonClicked"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toRightOf="@id/pan_down"
|
||||
android:text="@string/right_arrow"
|
||||
android:layout_toEndOf="@id/pan_down" />
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="end"
|
||||
android:orientation="vertical">
|
||||
|
||||
<Button
|
||||
android:id="@+id/zoom_in"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="48dp"
|
||||
android:onClick="onButtonClicked"
|
||||
android:text="@string/zoom_in" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/zoom_out"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="48dp"
|
||||
android:onClick="onButtonClicked"
|
||||
android:text="@string/zoom_out" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:text="@string/duration" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/duration_bar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:progress="1000"
|
||||
android:max="5000" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:id="@+id/sydney"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:onClick="onGoToLocation"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/go_to_sydney"
|
||||
style="?android:attr/borderlessButtonStyle" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/sanfrancisco"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:onClick="onGoToLocation"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/go_to_san_francisco"
|
||||
style="?android:attr/borderlessButtonStyle" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/santorini"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:onClick="onGoToLocation"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/go_to_santorini"
|
||||
style="?android:attr/borderlessButtonStyle" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/invalid"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:onClick="onGoToLocation"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/go_to_invalid"
|
||||
style="?android:attr/borderlessButtonStyle" />
|
||||
</LinearLayout>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/streetviewpanorama"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
class="com.google.android.gms.maps.SupportStreetViewPanoramaFragment" />
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,112 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/map_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/map"
|
||||
android:name="com.google.android.gms.maps.SupportMapFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="175dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginBottom="25dp"
|
||||
android:clipToPadding="false">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/checkbox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:background="@color/white">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/zoom_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClick"
|
||||
android:text="@string/checkbox_zoom" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/compass_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClick"
|
||||
android:text="@string/checkbox_compass" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/myloc_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClick"
|
||||
android:text="@string/checkbox_my_location_layer" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/level_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClick"
|
||||
android:text="@string/checkbox_level_picker" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/maptoolbar_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClick"
|
||||
android:text="@string/checkbox_map_toolbar" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/zoomgest_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClick"
|
||||
android:text="@string/checkbox_zoom_gesture" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/scrollgest_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClick"
|
||||
android:text="@string/checkbox_scroll_gesture" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/tiltgest_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClick"
|
||||
android:text="@string/checkbox_tilt_gesture" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/rotategest_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClick"
|
||||
android:text="@string/checkbox_rotate_gesture" />
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</RelativeLayout>
|
||||
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:map="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="5dp">
|
||||
|
||||
<!-- Put the name of the location and the map inside a CardView -->
|
||||
<android.support.v7.widget.CardView
|
||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/card_view"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="2dp"
|
||||
card_view:cardCornerRadius="0dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
<TextView
|
||||
android:id="@+id/lite_listrow_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:layout_alignParentTop="true"/>
|
||||
|
||||
<!-- MapView in lite mode. Note that it needs to be initialised
|
||||
programmatically before it can be used. -->
|
||||
<com.google.android.gms.maps.MapView
|
||||
android:id="@+id/lite_listrow_map"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="150dp"
|
||||
map:liteMode="true"
|
||||
map:mapType="none"
|
||||
android:layout_below="@id/lite_listrow_text" />
|
||||
</RelativeLayout>
|
||||
</android.support.v7.widget.CardView>
|
||||
</LinearLayout>
|
||||
30
ApiDemos/kotlin/app/src/main/res/menu/lite_list_menu.xml
Normal file
30
ApiDemos/kotlin/app/src/main/res/menu/lite_list_menu.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2018 Google LLC
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/layout_linear"
|
||||
android:title="@string/linear"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/layout_grid"
|
||||
android:title="@string/grid"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
||||
@ -19,6 +19,10 @@
|
||||
<string name="no_demos">No demos</string>
|
||||
<string name="play_services_not_installed">Google Play services is not installed on this device.</string>
|
||||
|
||||
<!-- Basic Map Demo -->
|
||||
<string name="basic_demo_label">Basic Map</string>
|
||||
<string name="basic_demo_details">Launches a map with marker pointing at Sydney.</string>
|
||||
|
||||
<!-- Camera Demo -->
|
||||
<string name="animate">Animate</string>
|
||||
<string name="camera_demo_description">Demonstrates Camera Functions</string>
|
||||
@ -36,48 +40,14 @@
|
||||
<string name="zoom_in">+</string>
|
||||
<string name="zoom_out">-</string>
|
||||
|
||||
<!-- Tags Demo -->
|
||||
<string name="tags_demo_label">Tags</string>
|
||||
<string name="tags_demo_details">Demonstrates how to get and set tags on API objects.</string>
|
||||
<string name="tags_demo_map_description">Map with a circle, ground overlay, marker, polygon and polyline.</string>
|
||||
<!-- Circle Demo -->
|
||||
<string name="circle_demo_label">Circle Demo</string>
|
||||
<string name="circle_demo_details">Demonstrate how to add circles to a map</string>
|
||||
<string name="properties_circle">Properties for Circle(s)</string>
|
||||
|
||||
<!-- Polygon Demo -->
|
||||
<string name="clickable">Clickable</string>
|
||||
<string name="fill_alpha">Fill Alpha</string>
|
||||
<string name="fill_hue">Fill Hue</string>
|
||||
<string name="joint_type_bevel">Bevel</string>
|
||||
<string name="joint_type_default">Default</string>
|
||||
<string name="joint_type_round">Round</string>
|
||||
<string name="pattern_dashed">Dashed</string>
|
||||
<string name="pattern_dotted">Dotted</string>
|
||||
<string name="pattern_mixed">Mixed</string>
|
||||
<string name="pattern_solid">Solid</string>
|
||||
<string name="polygon_demo_description">Demonstrates how to add Polygons to a map.</string>
|
||||
<string name="polygon_demo_details">Demonstrates how to add Polygons to a map</string>
|
||||
<string name="polygon_demo_label">Polygons</string>
|
||||
<string name="properties_australia_polygon">Properties for Polygon over Australia</string>
|
||||
<string name="stroke_alpha">Stroke Alpha</string>
|
||||
<string name="stroke_hue">Stroke Hue</string>
|
||||
<string name="stroke_joint_type">Stroke Joint Type</string>
|
||||
<string name="stroke_pattern">Stroke Pattern</string>
|
||||
<string name="stroke_width">Stroke Width</string>
|
||||
|
||||
<!-- Markers Demo -->
|
||||
<string name="custom_info_contents">Custom Info Contents</string>
|
||||
<string name="custom_info_window">Custom Info Window</string>
|
||||
<string name="default_info_window">Default Info Window</string>
|
||||
<string name="drag_melbourne">Drag Melbourne</string>
|
||||
<string name="clear_map">Clear</string>
|
||||
<string name="flat">Flat</string>
|
||||
<string name="reset_map">Reset</string>
|
||||
<string name="map_not_ready">Map is not ready</string>
|
||||
<string name="markers_demo_description">Demonstrates how to add Markers to a map.</string>
|
||||
<string name="markers_demo_label">Markers</string>
|
||||
<string name="on_marker_drag">onMarkerDrag. Current Position: (%1$f, %2$f)</string>
|
||||
<string name="on_marker_drag_start">Started dragging marker</string>
|
||||
<string name="on_marker_drag_end">Marker stopped dragging</string>
|
||||
<string name="rotation">Rotation</string>
|
||||
<string name="state_badge_label">State badge</string>
|
||||
<!-- Close Info Window On Retap Demo -->
|
||||
<string name="close_info_window_demo_label">Close Info Window Demo</string>
|
||||
<string name="close_info_window_demo_details">Demonstrates how to close the info window when the currently selected marker is retapped.</string>
|
||||
|
||||
<!-- Layers Demo -->
|
||||
<string name="buildings">Buildings</string>
|
||||
@ -100,11 +70,55 @@
|
||||
<string name="terrain">Terrain</string>
|
||||
<string name="traffic">Traffic</string>
|
||||
|
||||
<!-- Lite List Demo -->
|
||||
<string name="lite_list_demo_label">Lite List Demo</string>
|
||||
<string name="lite_list_demo_details">Show a list of Lite Map of different locations using RecyclerView with LinearLayoutManager and GridLayoutManager</string>
|
||||
<string name="linear">Linear</string>
|
||||
<string name="grid">Grid</string>
|
||||
|
||||
<!-- Markers Demo -->
|
||||
<string name="custom_info_contents">Custom Info Contents</string>
|
||||
<string name="custom_info_window">Custom Info Window</string>
|
||||
<string name="default_info_window">Default Info Window</string>
|
||||
<string name="drag_melbourne">Drag Melbourne</string>
|
||||
<string name="clear_map">Clear</string>
|
||||
<string name="flat">Flat</string>
|
||||
<string name="reset_map">Reset</string>
|
||||
<string name="map_not_ready">Map is not ready</string>
|
||||
<string name="markers_demo_description">Demonstrates how to add Markers to a map.</string>
|
||||
<string name="markers_demo_label">Markers</string>
|
||||
<string name="on_marker_drag">onMarkerDrag. Current Position: (%1$f, %2$f)</string>
|
||||
<string name="on_marker_drag_start">Started dragging marker</string>
|
||||
<string name="on_marker_drag_end">Marker stopped dragging</string>
|
||||
<string name="rotation">Rotation</string>
|
||||
<string name="state_badge_label">State badge</string>
|
||||
|
||||
<!-- Permissions -->
|
||||
<string name="permission_rationale_location">Access to the location service is required to demonstrate the \'my location\' feature, which shows your current location on the map.</string>
|
||||
<string name="location_permission_denied">This sample requires location permission to enable the \'my location\' layer. Please try again and grant access to use the location.\nIf the permission has been permanently denied, it can be enabled from the System Settings > Apps > \'Google Maps API Demos\'.</string>
|
||||
<string name="permission_required_toast">Location permission is required for this demo.</string>
|
||||
|
||||
<!-- Polygon Demo -->
|
||||
<string name="clickable">Clickable</string>
|
||||
<string name="fill_alpha">Fill Alpha</string>
|
||||
<string name="fill_hue">Fill Hue</string>
|
||||
<string name="joint_type_bevel">Bevel</string>
|
||||
<string name="joint_type_default">Default</string>
|
||||
<string name="joint_type_round">Round</string>
|
||||
<string name="pattern_dashed">Dashed</string>
|
||||
<string name="pattern_dotted">Dotted</string>
|
||||
<string name="pattern_mixed">Mixed</string>
|
||||
<string name="pattern_solid">Solid</string>
|
||||
<string name="polygon_demo_description">Demonstrates how to add Polygons to a map.</string>
|
||||
<string name="polygon_demo_details">Demonstrates how to add Polygons to a map</string>
|
||||
<string name="polygon_demo_label">Polygons</string>
|
||||
<string name="properties_australia_polygon">Properties for Polygon over Australia</string>
|
||||
<string name="stroke_alpha">Stroke Alpha</string>
|
||||
<string name="stroke_hue">Stroke Hue</string>
|
||||
<string name="stroke_joint_type">Stroke Joint Type</string>
|
||||
<string name="stroke_pattern">Stroke Pattern</string>
|
||||
<string name="stroke_width">Stroke Width</string>
|
||||
|
||||
<!-- Polylines Demo -->
|
||||
<string name="alpha">Alpha</string>
|
||||
<string name="cap_butt">Butt</string>
|
||||
@ -120,6 +134,34 @@
|
||||
<string name="start_cap">Start Cap</string>
|
||||
<string name="width">Width</string>
|
||||
|
||||
<!-- StreetView Panorama Navigation Demo -->
|
||||
<string name="street_view_panorama_navigation_demo_label">Street View Panorama Navigation Demo</string>
|
||||
<string name="street_view_panorama_navigation_demo_details">Street View Panorama with programmatic navigation</string>
|
||||
<string name="request_position">Position</string>
|
||||
<string name="walk_panorama">Walk</string>
|
||||
<string name="go_to_invalid">Go to Invalid Point</string>
|
||||
<string name="go_to_san_francisco">Go to San Francisco</string>
|
||||
<string name="go_to_santorini">Go to Santorini</string>
|
||||
|
||||
<!-- Tags Demo -->
|
||||
<string name="tags_demo_label">Tags</string>
|
||||
<string name="tags_demo_details">Demonstrates how to get and set tags on API objects.</string>
|
||||
<string name="tags_demo_map_description">Map with a circle, ground overlay, marker, polygon and polyline.</string>
|
||||
|
||||
<!-- UI Settings Demo -->
|
||||
<string name="ui_settings_demo_label">UI Settings Demo</string>
|
||||
<string name="ui_settings_demo_details">Demonstrate how to toggle the UI of a map</string>
|
||||
<string name="location">Location permission is required to run the demo</string>
|
||||
<string name="checkbox_zoom">Zoom</string>
|
||||
<string name="checkbox_compass">Compass</string>
|
||||
<string name="checkbox_my_location_layer">My Location</string>
|
||||
<string name="checkbox_level_picker">Level Picker</string>
|
||||
<string name="checkbox_map_toolbar">Map Toolbar</string>
|
||||
<string name="checkbox_zoom_gesture">Zoom Gestures</string>
|
||||
<string name="checkbox_scroll_gesture">Scroll Gestures</string>
|
||||
<string name="checkbox_tilt_gesture">Tilt Gestures</string>
|
||||
<string name="checkbox_rotate_gesture">Rotate Gestures</string>
|
||||
|
||||
<!-- Visible Regions Demo -->
|
||||
<string name="camera_change_message">CameraChangeListener: %1$s</string>
|
||||
<string name="region_demo_label">Visible Regions</string>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user