Skip to content

Commit 38b5735

Browse files
committed
refactor(PlaceDetailPreview): PlaceDetailPreviewSecondaryFragment Compose ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜
๊ธฐ์กด View ์‹œ์Šคํ…œ ๊ธฐ๋ฐ˜์˜ `PlaceDetailPreviewSecondaryFragment`๋ฅผ Jetpack Compose๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜์—ฌ UI ๊ตฌํ˜„ ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค. - **`PlaceDetailPreviewSecondaryFragment.kt` ์ˆ˜์ •:** - `onViewCreated` ๋ฐ ViewBinding ๊ด€๋ จ ๋กœ์ง์„ ์ œ๊ฑฐํ•˜๊ณ , `onCreateView`์—์„œ `ComposeView`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค. - `PlaceDetailPreviewSecondaryScreen` ์ปดํฌ์ €๋ธ”์„ ์‚ฌ์šฉํ•˜์—ฌ UI๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ , `viewModel.selectedPlaceFlow`๋ฅผ `collectAsStateWithLifecycle`๋กœ ๊ตฌ๋…ํ•˜์—ฌ ์ƒํƒœ๋ฅผ ์ „๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค. - ๋’ค๋กœ ๊ฐ€๊ธฐ ์ฝœ๋ฐฑ(`OnBackPressedCallback`) ํ™œ์„ฑํ™” ๋กœ์ง์„ `LaunchedEffect` ๋‚ด์—์„œ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค. - ํด๋ฆญ ์‹œ ๋ฐœ์ƒํ•˜๋Š” ๋กœ๊ทธ ๊ธฐ๋ก ๋กœ์ง(`PlacePreviewClick`)์„ ์ปดํฌ์ €๋ธ”์˜ `onClick` ์ฝœ๋ฐฑ์œผ๋กœ ์ด๋™์‹œ์ผฐ์Šต๋‹ˆ๋‹ค. - **`PlaceDetailPreviewSecondaryScreen.kt` ์ˆ˜์ •:** - ์ปดํฌ๋„ŒํŠธ ์ „์ฒด์— ํด๋ฆญ ์ด๋ฒคํŠธ๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด `onClick` ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  `clickable` Modifier๋ฅผ ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. - `PreviewAnimatableBox`์— `fillMaxWidth` Modifier์™€ `shape`(`radius2`) ์„ค์ •์„ ์ถ”๊ฐ€ํ•˜์—ฌ UI ๋ ˆ์ด์•„์›ƒ์„ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.
1 parent 1043f84 commit 38b5735

File tree

2 files changed

+77
-51
lines changed

2 files changed

+77
-51
lines changed
Lines changed: 65 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,36 @@
11
package com.daedan.festabook.presentation.placeMap.placeDetailPreview
22

33
import android.os.Bundle
4+
import android.view.LayoutInflater
45
import android.view.View
6+
import android.view.ViewGroup
57
import androidx.activity.OnBackPressedCallback
8+
import androidx.compose.foundation.layout.Box
9+
import androidx.compose.foundation.layout.fillMaxSize
10+
import androidx.compose.foundation.layout.padding
11+
import androidx.compose.runtime.LaunchedEffect
12+
import androidx.compose.runtime.getValue
13+
import androidx.compose.ui.Alignment
14+
import androidx.compose.ui.Modifier
15+
import androidx.compose.ui.platform.ComposeView
16+
import androidx.compose.ui.platform.ViewCompositionStrategy
617
import androidx.fragment.app.Fragment
718
import androidx.fragment.app.viewModels
819
import androidx.lifecycle.ViewModelProvider
9-
import coil3.load
20+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
1021
import com.daedan.festabook.R
1122
import com.daedan.festabook.databinding.FragmentPlaceDetailPreviewSecondaryBinding
23+
import com.daedan.festabook.di.appGraph
1224
import com.daedan.festabook.di.fragment.FragmentKey
13-
import com.daedan.festabook.logging.logger
1425
import com.daedan.festabook.presentation.common.BaseFragment
1526
import com.daedan.festabook.presentation.common.OnMenuItemReClickListener
16-
import com.daedan.festabook.presentation.common.showBottomAnimation
1727
import com.daedan.festabook.presentation.common.showErrorSnackBar
18-
import com.daedan.festabook.presentation.placeDetail.model.PlaceDetailUiModel
1928
import com.daedan.festabook.presentation.placeMap.PlaceMapViewModel
2029
import com.daedan.festabook.presentation.placeMap.logging.PlacePreviewClick
2130
import com.daedan.festabook.presentation.placeMap.model.SelectedPlaceUiState
22-
import com.daedan.festabook.presentation.placeMap.model.getIconId
23-
import com.daedan.festabook.presentation.placeMap.model.getTextId
31+
import com.daedan.festabook.presentation.placeMap.placeDetailPreview.component.PlaceDetailPreviewSecondaryScreen
32+
import com.daedan.festabook.presentation.theme.FestabookTheme
33+
import com.daedan.festabook.presentation.theme.festabookSpacing
2434
import dev.zacsweers.metro.AppScope
2535
import dev.zacsweers.metro.ContributesIntoMap
2636
import dev.zacsweers.metro.Inject
@@ -43,56 +53,62 @@ class PlaceDetailPreviewSecondaryFragment(
4353
}
4454
}
4555

46-
override fun onViewCreated(
47-
view: View,
56+
override fun onCreateView(
57+
inflater: LayoutInflater,
58+
container: ViewGroup?,
4859
savedInstanceState: Bundle?,
49-
) {
50-
super.onViewCreated(view, savedInstanceState)
51-
setUpObserver()
52-
setUpBackPressedCallback()
53-
}
54-
55-
override fun onMenuItemReClick() {
56-
viewModel.unselectPlace()
57-
}
60+
): View {
61+
return ComposeView(requireContext()).apply {
62+
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
63+
setContent {
64+
val placeDetailUiState by viewModel.selectedPlaceFlow.collectAsStateWithLifecycle()
65+
val visible = placeDetailUiState is SelectedPlaceUiState.Success
5866

59-
private fun setUpBackPressedCallback() {
60-
requireActivity().onBackPressedDispatcher.addCallback(
61-
viewLifecycleOwner,
62-
backPressedCallback,
63-
)
64-
}
65-
66-
private fun setUpObserver() {
67-
viewModel.selectedPlace.observe(viewLifecycleOwner) { selectedPlace ->
68-
backPressedCallback.isEnabled = true
69-
when (selectedPlace) {
70-
is SelectedPlaceUiState.Success -> {
71-
binding.layoutSelectedPlace.visibility = View.VISIBLE
72-
binding.layoutSelectedPlace.showBottomAnimation()
73-
updateSelectedPlaceUi(selectedPlace.value)
74-
binding.logger.log(
75-
PlacePreviewClick(
76-
baseLogData = binding.logger.getBaseLogData(),
77-
placeName = selectedPlace.value.place.title ?: "undefined",
78-
timeTag = viewModel.selectedTimeTag.value?.name ?: "undefined",
79-
category = selectedPlace.value.place.category.name,
80-
),
81-
)
67+
LaunchedEffect(placeDetailUiState) {
68+
backPressedCallback.isEnabled = true
8269
}
8370

84-
is SelectedPlaceUiState.Error -> showErrorSnackBar(selectedPlace.throwable)
85-
is SelectedPlaceUiState.Loading -> Unit
86-
is SelectedPlaceUiState.Empty -> backPressedCallback.isEnabled = false
71+
FestabookTheme {
72+
Box(
73+
modifier = Modifier.fillMaxSize(),
74+
contentAlignment = Alignment.BottomCenter,
75+
) {
76+
PlaceDetailPreviewSecondaryScreen(
77+
visible = visible,
78+
placeUiState = placeDetailUiState,
79+
modifier =
80+
Modifier
81+
.padding(
82+
vertical = festabookSpacing.paddingBody4,
83+
horizontal = festabookSpacing.paddingScreenGutter,
84+
),
85+
onError = {
86+
showErrorSnackBar(it.throwable)
87+
},
88+
onEmpty = {
89+
backPressedCallback.isEnabled = false
90+
},
91+
onClick = {
92+
if (it !is SelectedPlaceUiState.Success) return@PlaceDetailPreviewSecondaryScreen
93+
appGraph.defaultFirebaseLogger.log(
94+
PlacePreviewClick(
95+
baseLogData = appGraph.defaultFirebaseLogger.getBaseLogData(),
96+
placeName = it.value.place.title ?: "undefined",
97+
timeTag =
98+
viewModel.selectedTimeTag.value?.name
99+
?: "undefined",
100+
category = it.value.place.category.name,
101+
),
102+
)
103+
},
104+
)
105+
}
106+
}
87107
}
88108
}
89109
}
90110

91-
private fun updateSelectedPlaceUi(selectedPlace: PlaceDetailUiModel) {
92-
with(binding) {
93-
ivSecondaryCategoryItem.load(selectedPlace.place.category.getIconId())
94-
tvSelectedPlaceTitle.text =
95-
selectedPlace.place.title ?: getString(selectedPlace.place.category.getTextId())
96-
}
111+
override fun onMenuItemReClick() {
112+
viewModel.unselectPlace()
97113
}
98114
}

โ€Žapp/src/main/java/com/daedan/festabook/presentation/placeMap/placeDetailPreview/component/PlaceDetailPreviewSecondaryScreen.ktโ€Ž

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.daedan.festabook.presentation.placeMap.placeDetailPreview.component
22

3+
import androidx.compose.foundation.clickable
34
import androidx.compose.foundation.layout.Row
5+
import androidx.compose.foundation.layout.fillMaxWidth
46
import androidx.compose.foundation.layout.padding
57
import androidx.compose.foundation.layout.size
68
import androidx.compose.material3.Icon
@@ -22,6 +24,7 @@ import com.daedan.festabook.presentation.placeMap.model.getIconId
2224
import com.daedan.festabook.presentation.placeMap.model.getTextId
2325
import com.daedan.festabook.presentation.theme.FestabookTheme
2426
import com.daedan.festabook.presentation.theme.FestabookTypography
27+
import com.daedan.festabook.presentation.theme.festabookShapes
2528
import com.daedan.festabook.presentation.theme.festabookSpacing
2629

2730
@Composable
@@ -30,11 +33,18 @@ fun PlaceDetailPreviewSecondaryScreen(
3033
modifier: Modifier = Modifier,
3134
onError: (SelectedPlaceUiState.Error) -> Unit = {},
3235
onEmpty: () -> Unit = {},
36+
onClick: (SelectedPlaceUiState) -> Unit = {},
3337
visible: Boolean = false,
3438
) {
3539
PreviewAnimatableBox(
3640
visible = visible,
37-
modifier = modifier,
41+
modifier =
42+
modifier
43+
.fillMaxWidth()
44+
.clickable {
45+
onClick(placeUiState)
46+
},
47+
shape = festabookShapes.radius2,
3848
) {
3949
when (placeUiState) {
4050
is SelectedPlaceUiState.Loading -> Unit
@@ -96,7 +106,7 @@ private val FAKE_PLACE =
96106
id = 1,
97107
imageUrl = null,
98108
category = PlaceCategoryUiModel.TOILET,
99-
title = "ํ…Œ์ŠคํŠธํ…Œ์ŠคํŠธํ…Œ์ŠคํŠธํ…Œ์ŠคํŠธํ…Œ์ŠคํŠธํ…Œ์ŠคํŠธํ…Œ์ŠคํŠธํ…Œ์ŠคํŠธํ…Œ์ŠคํŠธํ…Œ์ŠคํŠธํ…Œ์ŠคํŠธํ…Œ์ŠคํŠธํ…Œ์ŠคํŠธ",
109+
title = "ํ…Œ์ŠคํŠธํ…Œ์Šค",
100110
description = "https://onlyfor-me-blog.tistory.com/1190",
101111
location = null,
102112
isBookmarked = false,

0 commit comments

Comments
ย (0)