mirror of
https://github.com/googlemaps/android-samples.git
synced 2025-12-08 18:02:20 +00:00
Merge branch 'kotlin-samples'
This commit is contained in:
commit
e041f1827b
@ -27,8 +27,16 @@ 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'
|
||||
implementation 'com.google.android.gms:play-services-maps:11.8.0'
|
||||
compile 'com.google.android.gms:play-services-location:11.8.0'
|
||||
|
||||
// EasyPermissions is needed to help us request for permission to access location
|
||||
implementation 'pub.devrel:easypermissions:1.1.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>
|
||||
@ -16,6 +16,9 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.kotlindemos">
|
||||
|
||||
<!-- Access to location is needed for the UI Settings Demo -->
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
@ -23,6 +26,11 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.android.geo.API_KEY"
|
||||
android:value="@string/google_maps_key" />
|
||||
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
@ -30,6 +38,12 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".BasicMapDemoActivity" />
|
||||
<activity android:name=".CircleDemoActivity" />
|
||||
<activity android:name=".CloseInfoWindowDemoActivity" />
|
||||
<activity android:name=".LiteListDemoActivity" />
|
||||
<activity android:name=".StreetViewPanoramaNavigationDemoActivity" />
|
||||
<activity android:name=".UiSettingsDemoActivity" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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) {
|
||||
with(googleMap) {
|
||||
moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, ZOOM_LEVEL))
|
||||
addMarker(MarkerOptions().position(SYDNEY))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,322 @@
|
||||
/*
|
||||
* 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() {
|
||||
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 as View
|
||||
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
|
||||
}
|
||||
|
||||
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")
|
||||
)
|
||||
}
|
||||
@ -21,6 +21,22 @@ package com.example.kotlindemos
|
||||
*/
|
||||
class DemoDetailsList {
|
||||
companion object {
|
||||
val DEMOS = listOf<DemoDetails>()
|
||||
val DEMOS = listOf<DemoDetails>(
|
||||
DemoDetails(R.string.basic_demo_label, R.string.basic_demo_details,
|
||||
BasicMapDemoActivity::class.java),
|
||||
DemoDetails(R.string.close_info_window_demo_label,
|
||||
R.string.close_info_window_demo_details,
|
||||
CloseInfoWindowDemoActivity::class.java),
|
||||
DemoDetails(R.string.circle_demo_label, R.string.circle_demo_details,
|
||||
CircleDemoActivity::class.java),
|
||||
DemoDetails(R.string.lite_list_demo_label, R.string.lite_list_demo_details,
|
||||
LiteListDemoActivity::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.ui_settings_demo_label, R.string.ui_settings_demo_details,
|
||||
UiSettingsDemoActivity::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)
|
||||
|
||||
@ -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,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.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>
|
||||
@ -3,4 +3,5 @@
|
||||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
<color name="white">#D0FFFFFF</color>
|
||||
</resources>
|
||||
|
||||
@ -18,4 +18,67 @@
|
||||
<string name="demo_title">Google Maps API Demos</string>
|
||||
<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>
|
||||
|
||||
<!-- 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>
|
||||
|
||||
<!-- 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>
|
||||
|
||||
<!-- Marker 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>
|
||||
|
||||
<!-- 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>
|
||||
|
||||
<!-- 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>
|
||||
|
||||
<!-- 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>
|
||||
</resources>
|
||||
Loading…
x
Reference in New Issue
Block a user