本篇文章同步发表在 HKT 线上教室 部落格,线上影音教学课程已上架至 Udemy 和 Youtube 频道。另外,想追踪更多相关技术资讯,欢迎到 脸书粉丝专页 按赞追踪喔~
范例名称:Google Map 显示目前位置
开发人员:HKT (侯光灿)
程序语言:Kotlin
开发环境:Android Studio 4.1.2 & Android 11 & Kotlin 1.4.30
授权范围:使用时必须注明出处且不得为商业目的之使用
范例下载点:点我下载
范例名称:清除标记
开发人员:HKT (侯光灿)
程序语言:Kotlin
开发环境:Android Studio 4.1.2 & Android 11 & Kotlin 1.4.30
授权范围:使用时必须注明出处且不得为商业目的之使用
范例下载点:点我下载
范例名称:目前所在位置,使用预设蓝色小点呈现
开发人员:HKT (侯光灿)
程序语言:Kotlin
开发环境:Android Studio 4.1.2 & Android 11 & Kotlin 1.4.30
授权范围:使用时必须注明出处且不得为商业目的之使用
范例下载点:点我下载
在之前的介绍当中,我们陆陆续续学会「如何获取位置权限」、「如何检查GPS是否开启」、「如何获取目前所在位置经纬度」和「 Google Map 基本使用方式」,综合以上几个单元的学习,今天,我们已经可以轻松做出,在 Google Map 上标示并显示目前装置所在位置的 APP 应用程序。
将昨天介绍的范例,部分区域变数,拉出来变为全域变数
private var googleMap: GoogleMap? = null
private lateinit var mFusedLocationProviderClient: FusedLocationProviderClient
原本 getLocationPermission 写在 onCreate ,我们将他搬到 onMapReady,代表等地图准备好,我们再去检查与获取权限与位置逻辑。
override fun onMapReady(googleMap: GoogleMap) {
this.googleMap = googleMap
getLocationPermission()
}
在 onLocationResult 里,将获取到经纬度指定到 currentLocation,透过地图的 addMarker 将所在位置标示出来,然後透过 moveCamera 将地图画面移动到此处。
val currentLocation =
LatLng(
locationResult.lastLocation.latitude,
locationResult.lastLocation.longitude
)
googleMap?.addMarker(
MarkerOptions().position(currentLocation).title("现在位置")
)
googleMap?.moveCamera(
CameraUpdateFactory.newLatLngZoom(
currentLocation, 15f
)
)
假设装置位置不断在改变,但我们没有把旧的标记清掉,就会有很多之前位置点的标记。所以我们需要加入清除上一次标记的逻辑。
private var mCurrLocationMarker: Marker? = null
...
...
...
//清除所有标记
//googleMap?.clear()
//清除上一次位置标记
mCurrLocationMarker?.remove()
//当下位置存到一个 Marker 变数中,好让下一次可以清除
mCurrLocationMarker =googleMap?.addMarker(
MarkerOptions().position(currentLocation).title("现在位置")
)
Markers (标记、图钉),可以在地图呈现一个指引图案,吸引用户看这里。如图所示:
其中 MarkerOptions 常用属性,整理如下:
更多 Markers 设定可以参考官方文件: Markers。
设定 Markers 的 Icon 图片需为 bitmap,这里 KT 提供一个将向量图片转为 bitmap 的小程序。并扩充 Int 功能,新增转 dp 和 px 功能。
package com.thishkt.pharmacydemo.util
import android.content.Context
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import android.util.Log
import androidx.core.content.ContextCompat
import com.google.android.gms.maps.model.BitmapDescriptor
import com.google.android.gms.maps.model.BitmapDescriptorFactory
object ImgUtil {
fun getBitmapDescriptor(
context: Context,
id: Int,
width: Int = 0,
height: Int = 0
): BitmapDescriptor? {
val vectorDrawable: Drawable? =
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
context.getDrawable(id)
} else {
ContextCompat.getDrawable(context, id)
}
return if (vectorDrawable != null) {
if (width == 0) vectorDrawable.intrinsicWidth
if (height == 0) vectorDrawable.intrinsicHeight
vectorDrawable.setBounds(0, 0, width, height)
val bm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
val canvas = Canvas(bm);
vectorDrawable.draw(canvas);
BitmapDescriptorFactory.fromBitmap(bm);
} else {
null
}
}
val Int.dp: Int
get() = (this / Resources.getSystem().displayMetrics.density).toInt()
val Int.px: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
}
向量图片取自 Android Studio 内建的 mask 向量图,ic_baseline_masks_24.xml
<vector android:height="24dp" android:tint="#FF5722"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M19.5,6c-1.31,0 -2.37,1.01 -2.48,2.3C15.14,7.8 14.18,6.5 12,6.5c-2.19,0 -3.14,1.3 -5.02,1.8C6.87,7.02 5.81,6 4.5,6C3.12,6 2,7.12 2,8.5V9c0,6 3.6,7.81 6.52,7.98C9.53,17.62 10.72,18 12,18s2.47,-0.38 3.48,-1.02C18.4,16.81 22,15 22,9V8.5C22,7.12 20.88,6 19.5,6zM3.5,9V8.5c0,-0.55 0.45,-1 1,-1s1,0.45 1,1v3c0,1.28 0.38,2.47 1.01,3.48C4.99,14.27 3.5,12.65 3.5,9zM20.5,9c0,3.65 -1.49,5.27 -3.01,5.98c0.64,-1.01 1.01,-2.2 1.01,-3.48v-3c0,-0.55 0.45,-1 1,-1s1,0.45 1,1V9zM10.69,10.48c-0.44,0.26 -0.96,0.56 -1.69,0.76V10.2c0.48,-0.17 0.84,-0.38 1.18,-0.58C10.72,9.3 11.23,9 12,9s1.27,0.3 1.8,0.62c0.34,0.2 0.71,0.42 1.2,0.59v1.04c-0.75,-0.21 -1.26,-0.51 -1.71,-0.78C12.83,10.2 12.49,10 12,10C11.51,10 11.16,10.2 10.69,10.48z"/>
</vector>
MarkerOptions 设定参数
googleMap?.addMarker(
MarkerOptions()
.position(currentLocation).title("现在位置")
.snippet("这里可以显示相关资讯,太过长会被截掉").icon(
getBitmapDescriptor(
mContext,
R.drawable.ic_baseline_masks_24,
60.px,
60.px
)
)
)
在 onMapReady 加入移动镜头到预设座标位置,这样开启时预设就会先看到此位置。
//台北101
private val defaultLocation = LatLng(25.0338483, 121.5645283)
...
...
...
override fun onMapReady(googleMap: GoogleMap) {
...
googleMap.moveCamera(
CameraUpdateFactory.newLatLngZoom(
defaultLocation, 6f
)
)
}
Marker 有一个 showInfoWindow 方法,即可在不用点任何标记下,预设开启此标记的资讯视窗。
currLocationMarker?.showInfoWindow()
googleMap?.isMyLocationEnabled = true
HKT 线上教室
https://tw-hkt.blogspot.com/
Freepik
https://www.freepik.com/
Select Current Place and Show Details on a Map
https://developers.google.com/maps/documentation/android-sdk/current-place-tutorial
MapsActivityCurrentPlace.kt
https://github.com/googlemaps/android-samples/blob/bb1492036ad171443f549054c7e750dfe1a5cc64/tutorials/kotlin/CurrentPlaceDetailsOnMap/app/src/main/java/com/example/currentplacedetailsonmap/MapsActivityCurrentPlace.kt
那今天【iThome 铁人赛】就介绍到这边罗~
顺带一提,KT 线上教室,脸书粉丝团,会不定期发布相关资讯,不想错过最新资讯,不要忘记来按赞,追踪喔!也欢迎大家将这篇文章分享给更多人喔。
我们明天再见罗!!!掰掰~
<<: Turbo Pascal 语言和你 SAY HELLO!!
>>: Day 13 Mailhog - 模拟 SMTP 邮件服务的开发利器
点开Project Settings的other,把Scripting Backend改为IL2CP...
更多会员限定文章可以到patreon观看 可以用现成的Dockerfile会更快 (包含一键布署) ...
JavaScript 条件语句基於不同的条件来执行不同的动作,通常在写代码时,总是需要为不同的决定来...
Windows 10允许您创建复原磁碟机,以便您可以使用该装置将Windows 10复原到以前的日期...
今天稍微测试了一下 OpenCart 4.0,很多地方不同於 OpenCart 3,之前光是看到规格...