Skip to content

Commit 5948ea1

Browse files
bngshyonghanJu
andcommitted
✨ 네이버맵 locationButton 커스텀 구현
Co-authored-by: yonghanJu <[email protected]>
1 parent 6567965 commit 5948ea1

File tree

6 files changed

+91
-2
lines changed

6 files changed

+91
-2
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.whyranoid.presentation.running
2+
3+
sealed interface Event {
4+
data class TrackingButtonClick(val mode: TrackingMode) : Event
5+
}

presentation/src/main/java/com/whyranoid/presentation/running/RunningActivity.kt

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ package com.whyranoid.presentation.running
22

33
import android.os.Bundle
44
import androidx.activity.viewModels
5+
import com.naver.maps.geometry.LatLng
6+
import com.naver.maps.map.CameraUpdate
7+
import com.naver.maps.map.LocationSource
8+
import com.naver.maps.map.LocationTrackingMode
59
import com.naver.maps.map.MapView
610
import com.naver.maps.map.NaverMap
711
import com.naver.maps.map.OnMapReadyCallback
@@ -52,6 +56,13 @@ internal class RunningActivity :
5256
locationOverlay.iconHeight = MAP_ICON_SIZE
5357
}
5458

59+
observeStateOnMapReady()
60+
naverMap.addOnCameraChangeListener { reason, animated ->
61+
if (reason == CameraUpdate.REASON_GESTURE) {
62+
viewModel.onTrackingCanceledByGesture()
63+
}
64+
}
65+
5566
paths = mutableListOf()
5667

5768
repeatWhenUiStarted {
@@ -129,6 +140,26 @@ internal class RunningActivity :
129140
}
130141
}
131142

143+
private fun observeStateOnMapReady() {
144+
repeatWhenUiStarted {
145+
viewModel.trackingModeState.collect { trackingMode ->
146+
when (trackingMode) {
147+
TrackingMode.NONE -> {
148+
naverMap.locationTrackingMode = LocationTrackingMode.NoFollow
149+
}
150+
TrackingMode.NO_FOLLOW -> {
151+
viewModel.runningState.value.runningData.lastLocation?.let { location ->
152+
naverMap.moveCamera(CameraUpdate.scrollTo(LatLng(location)))
153+
}
154+
}
155+
TrackingMode.FOLLOW -> {
156+
naverMap.locationTrackingMode = LocationTrackingMode.Follow
157+
}
158+
}
159+
}
160+
}
161+
}
162+
132163
private fun provideMogakrunPath(): PathOverlay {
133164
return PathOverlay().apply {
134165
color = getColor(R.color.mogakrun_secondary_light)
@@ -171,6 +202,6 @@ internal class RunningActivity :
171202
companion object {
172203
const val MAP_MAX_ZOOM = 18.0
173204
const val MAP_MIN_ZOOM = 10.0
174-
const val MAP_ICON_SIZE = 80
205+
const val MAP_ICON_SIZE = 50
175206
}
176207
}

presentation/src/main/java/com/whyranoid/presentation/running/RunningViewModel.kt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ import androidx.work.WorkManager
1313
import com.whyranoid.domain.usecase.StartRunningUseCase
1414
import dagger.hilt.android.lifecycle.HiltViewModel
1515
import dagger.hilt.android.qualifiers.ApplicationContext
16+
import kotlinx.coroutines.flow.MutableSharedFlow
17+
import kotlinx.coroutines.flow.MutableStateFlow
18+
import kotlinx.coroutines.flow.asSharedFlow
19+
import kotlinx.coroutines.flow.asStateFlow
1620
import kotlinx.coroutines.launch
1721
import javax.inject.Inject
1822

@@ -25,6 +29,12 @@ class RunningViewModel @Inject constructor(
2529

2630
val runningState = runningRepository.runningState
2731

32+
private val _trackingModeState = MutableStateFlow(TrackingMode.FOLLOW)
33+
val trackingModeState get() = _trackingModeState.asStateFlow()
34+
35+
private val _eventFlow = MutableSharedFlow<Event>()
36+
val eventFlow get() = _eventFlow.asSharedFlow()
37+
2838
init {
2939
if (runningRepository.runningState.value is RunningState.NotRunning) {
3040
viewModelScope.launch {
@@ -64,6 +74,24 @@ class RunningViewModel @Inject constructor(
6474
}
6575
}
6676

77+
fun onTrackingButtonClicked() {
78+
when (trackingModeState.value) {
79+
TrackingMode.NONE -> {
80+
_trackingModeState.value = TrackingMode.NO_FOLLOW
81+
}
82+
TrackingMode.NO_FOLLOW -> {
83+
_trackingModeState.value = TrackingMode.FOLLOW
84+
}
85+
TrackingMode.FOLLOW -> {
86+
_trackingModeState.value = TrackingMode.NONE
87+
}
88+
}
89+
}
90+
91+
fun onTrackingCanceledByGesture() {
92+
_trackingModeState.value = TrackingMode.NONE
93+
}
94+
6795
private fun onPauseButtonClicked() {
6896
runningRepository.pauseRunning()
6997
}
@@ -72,6 +100,12 @@ class RunningViewModel @Inject constructor(
72100
runningRepository.resumeRunning()
73101
}
74102

103+
private fun emitEvent(event: Event) {
104+
viewModelScope.launch {
105+
_eventFlow.emit(event)
106+
}
107+
}
108+
75109
fun onFinishButtonClicked() {
76110
// TODO: 액티비티에 이벤트 알려주기
77111
runningRepository.finishRunning()
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.whyranoid.presentation.running
2+
3+
enum class TrackingMode {
4+
NONE, NO_FOLLOW, FOLLOW
5+
}

presentation/src/main/res/layout/activity_running.xml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,29 @@
1717
<com.naver.maps.map.MapView
1818
android:id="@+id/map_view"
1919
android:layout_width="match_parent"
20-
android:layout_height="match_parent" />
20+
android:layout_height="match_parent"
21+
app:navermap_tiltGesturesEnabled="false" />
22+
23+
<com.google.android.material.button.MaterialButton
24+
android:id="@+id/btn_map_location"
25+
android:layout_width="50dp"
26+
android:layout_height="50dp"
27+
android:text="@string/running_map_location_button"
28+
android:onClick="@{() -> vm.onTrackingButtonClicked()}"
29+
app:layout_constraintBottom_toTopOf="@id/panel_running_data"
30+
app:layout_constraintRight_toRightOf="@id/panel_running_data" />
31+
2132

2233
<androidx.constraintlayout.widget.ConstraintLayout
34+
android:id="@+id/panel_running_data"
2335
android:layout_width="0dp"
2436
android:layout_height="wrap_content"
2537
android:layout_margin="12dp"
2638
android:background="@color/white"
2739
android:clickable="false"
2840
android:paddingHorizontal="12dp"
2941
android:paddingVertical="8dp"
42+
android:elevation="@dimen/cardview_default_elevation"
3043
app:layout_constraintBottom_toTopOf="@+id/btn_pause_or_resume"
3144
app:layout_constraintEnd_toEndOf="parent"
3245
app:layout_constraintStart_toStartOf="parent">

presentation/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
<string name="running_notification_title">달려~ 달려~</string>
9393
<string name="running_channel_name">활동 추적</string>
9494
<string name="running_channel_description">달리기 활동을 추적하는 알림 채널입니다.</string>
95+
<string name="running_map_location_button">🎯</string>
9596
<string name="text_join_group">그룹 가입하기</string>
9697
<string name="text_duplicated_group_name">중복된 그룹 이름입니다. 변경해주세요!</string>
9798
<string name="text_un_duplicated_group_name">사용 가능한 그룹 이름입니다!</string>

0 commit comments

Comments
 (0)