반응형
이번 장에는 Mapbox map에서 현재 유저 위치를 Puck을 활용해 표시하고 pulse effect까지 나타내는 작업을 진행하려고 한다.
현재 유저 위치를 디바이스로부터 가져오는 부분은 permission 작업과 더불어 FusedLocationProviderClient를 활용하여 진행하였으며 이번장에서는 해당 내용을 생략하려고 한다.
먼저 LocationProvider에 대한 정의가 필요한데, 아래와 같이 locationConsumer는 LocationProvider로부터 위치와 방위 업데이트를 받는다. 따라서 디바이스로부터 받은 현재 위치값을 locationConsumer에 전달하고, 이때의 LocationProvider는 mapview에 등록해주면 된다.
interface LocationProvider {
/**
* Register the location consumer to the Location Provider.
*
* The Location Consumer will get location and bearing updates from the Location Provider.
*
* @param locationConsumer
*/
fun registerLocationConsumer(locationConsumer: LocationConsumer)
/**
* Unregister the location consumer from the Location Provider.
*
* @param locationConsumer
*/
fun unRegisterLocationConsumer(locationConsumer: LocationConsumer)
}
위의 작업을 위해 LocationProvider를 상속받는 UserLocationProvider를 다음과 같이 작성하였으며 이를 Mapview에 등록하였다.
class UserLocationProvider: LocationProvider {
private var locationConsumer: LocationConsumer? = null
override fun registerLocationConsumer(locationConsumer: LocationConsumer) {
this.locationConsumer = locationConsumer
}
override fun unRegisterLocationConsumer(locationConsumer: LocationConsumer) {
this.locationConsumer = null
}
fun onLocationUpdated(latitude: Double, longitude: Double){
locationConsumer?.onLocationUpdated(Point.fromLngLat(longitude, latitude))
}
}
MapboxMap(
...
) {
MapEffect(key1 = Unit) {
it.location.setLocationProvider(mapViewModel.userLocationProvider)
}
}
ViewModel에서는 현재 위치 정보를 flow로 받도록 작업하여 새로운 데이터가 들어왔을때 위치정보를 업데이트할 수 있도록 작성하였다.
val location = getCurrentLocationUseCase().stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(),
Location(
latitude = 27.941584,
longitude = -82.450957,
)
).also {
viewModelScope.launch {
it.collectLatest { location ->
userLocationProvider.onLocationUpdated(location.latitude, location.longitude)
}
}
}
다음은 puck 작업인데, LocationPuck2D를 사용하였고 이때 커스텀된 이미지를 사용하고싶어 아래와 같이 추가하였다. pulse effect을 주기 위해서 pulsingEnabled를 true로 설정하였고, pulsing radius값까지 아래와 같이 설정해주었다.
MapboxMap(
...
locationComponentSettings = LocationComponentSettings(
LocationPuck2D(topImage = ImageHolder.Companion.from(R.drawable.ic_current_location_pin))
) {
enabled = true
pulsingEnabled = true
showAccuracyRing = true
pulsingMaxRadius = LocationComponentConstants.PULSING_MAX_RADIUS_FOLLOW_ACCURACY
},
) {
...
}
반응형
'Android' 카테고리의 다른 글
[Android] Canvas로 속도계 만들기 (0) | 2024.12.24 |
---|---|
Color 알파(alpha)값 계산기 개발기 (0) | 2024.09.13 |
[Android] Compose TextField 천단위 콤마(,) 설정하기 (1) | 2024.02.25 |
[Android] Github Pages로 프로젝트 문서 호스팅 (0) | 2024.02.18 |
[Android] Dokka를 활용하여 프로젝트 문서화하기 (0) | 2024.02.08 |