-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[refact/all]: App 추가화면 로직 수정 #158
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ import kotlinx.coroutines.flow.onEach | |
|
||
@AndroidEntryPoint | ||
class AppAddActivity : AppCompatActivity() { | ||
|
||
companion object { | ||
const val SELECTED_APPS = "selected_apps" | ||
const val GOAL_TIME = "goal_time" | ||
|
@@ -25,56 +26,43 @@ class AppAddActivity : AppCompatActivity() { | |
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
setContentView(binding.root) | ||
initViewPager() | ||
initNextButton() | ||
initViews() | ||
collectState() | ||
setOnClickBackButton() | ||
} | ||
|
||
private fun setOnClickBackButton() { | ||
binding.ivBack.setOnClickListener { | ||
finish() | ||
} | ||
} | ||
private fun initViews() { | ||
binding.run { | ||
vpAppAdd.adapter = AppAddViewPagerAdapter(this@AppAddActivity) | ||
vpAppAdd.isUserInputEnabled = false | ||
|
||
private fun collectState() { | ||
viewModel.state.flowWithLifecycle(lifecycle).onEach { | ||
binding.btAppSelection.isEnabled = it.selectedApp.isNotEmpty() | ||
}.launchIn(lifecycleScope) | ||
} | ||
btAppSelection.setOnClickListener { handleNextClicked() } | ||
ivBack.setOnClickListener { finish() } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 뒤로가기 버튼 눌렀을 때 이 액티비티를 종료하는 코드인 거 맞나요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넹 정답~!! |
||
|
||
private fun initNextButton() { | ||
binding.run { | ||
btAppSelection.setOnClickListener { | ||
handleNextClicked() | ||
} | ||
} | ||
|
||
} | ||
|
||
private fun ActivityAppAddBinding.handleNextClicked() { | ||
when (vpAppAdd.currentItem) { | ||
0 -> { | ||
vpAppAdd.currentItem = 1 | ||
} | ||
private fun collectState() { | ||
viewModel.state.flowWithLifecycle(lifecycle) | ||
.onEach { binding.btAppSelection.isEnabled = it.appSelectionList.isNotEmpty() } | ||
.launchIn(lifecycleScope) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이건 무슨 기능을 하는 코드인가요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. UDA 구조 -> 즉 단방향 데이터 통신을 통해 현재 View의 상태를 최신화 할 수 있도록 ViewModel에서 관리하는 State를 참조하도록 하는 코드입니다. |
||
} | ||
|
||
1 -> { | ||
val intent = Intent().apply { | ||
val selectedApps = viewModel.state.value.selectedApp | ||
putExtra(SELECTED_APPS, selectedApps.toTypedArray()) | ||
putExtra(GOAL_TIME, viewModel.state.value.goalTime) | ||
} | ||
setResult(RESULT_OK, intent) | ||
finish() | ||
private fun handleNextClicked() { | ||
binding.vpAppAdd.run { | ||
when (currentItem) { | ||
0 -> currentItem = 1 | ||
1 -> finishWithResults() | ||
} | ||
|
||
else -> Unit | ||
} | ||
} | ||
|
||
private fun initViewPager() { | ||
binding.vpAppAdd.run { | ||
adapter = AppAddViewPagerAdapter(this@AppAddActivity) | ||
isUserInputEnabled = false | ||
private fun finishWithResults() { | ||
val intent = Intent().apply { | ||
putExtra(SELECTED_APPS, viewModel.state.value.selectedApps.toTypedArray()) | ||
putExtra(GOAL_TIME, viewModel.state.value.goalTime) | ||
} | ||
setResult(RESULT_OK, intent) | ||
finish() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,81 @@ | ||
package com.hmh.hamyeonham.challenge.appadd | ||
|
||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.viewModelScope | ||
import com.hmh.hamyeonham.challenge.appadd.appselection.AppSelectionModel | ||
import com.hmh.hamyeonham.challenge.usecase.GetInstalledAppUseCase | ||
import dagger.hilt.android.lifecycle.HiltViewModel | ||
import kotlinx.coroutines.flow.MutableSharedFlow | ||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import kotlinx.coroutines.flow.asSharedFlow | ||
import kotlinx.coroutines.flow.asStateFlow | ||
import kotlinx.coroutines.launch | ||
import javax.inject.Inject | ||
|
||
sealed interface AppAddEffect { | ||
data class AppAdd(val selectedApp: List<String>, val goalTime: Long) : AppAddEffect | ||
} | ||
sealed interface AppAddEffect {} | ||
|
||
data class AppAddState( | ||
val selectedApp: List<String> = listOf(), | ||
val installedApp: List<String> = emptyList(), | ||
val selectedApps: List<String> = emptyList(), | ||
val goalHour: Long = 0, | ||
val goalMin: Long = 0, | ||
) { | ||
val goalTime = goalHour + goalMin | ||
val appSelectionList = installedApp.map { AppSelectionModel(it, selectedApps.contains(it)) } | ||
} | ||
|
||
@HiltViewModel | ||
class AppAddViewModel @Inject constructor() : ViewModel() { | ||
class AppAddViewModel @Inject constructor( | ||
private val getInstalledAppUseCase: GetInstalledAppUseCase | ||
) : ViewModel() { | ||
|
||
init { | ||
getInstalledApps() | ||
} | ||
|
||
private val _state = MutableStateFlow(AppAddState()) | ||
val state = _state.asStateFlow() | ||
|
||
private val _effect = MutableSharedFlow<AppAddEffect>() | ||
private val _effect = MutableSharedFlow<AppAddEffect>(1) | ||
val effect = _effect.asSharedFlow() | ||
|
||
fun updateState(transform: AppAddState.() -> AppAddState) { | ||
private fun updateState(transform: AppAddState.() -> AppAddState) { | ||
val currentState = state.value | ||
val newState = currentState.transform() | ||
_state.value = newState | ||
} | ||
|
||
Comment on lines
+42
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 상태 업데이트는 ViewModel에서만! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 구웃 |
||
fun checkApp(packageName: String) { | ||
updateState { | ||
copy(selectedApps = selectedApps + packageName) | ||
} | ||
|
||
} | ||
|
||
fun unCheckApp(packageName: String) { | ||
updateState { | ||
copy(selectedApps = selectedApps - packageName) | ||
} | ||
} | ||
|
||
fun setGoalHour(goalHour: Long) { | ||
updateState { | ||
copy(goalHour = goalHour) | ||
} | ||
} | ||
|
||
fun setGoalMin(goalMin: Long) { | ||
updateState { | ||
copy(goalMin = goalMin) | ||
} | ||
} | ||
Comment on lines
+61
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 시간이랑 분을 따로 업데이트 하는 거 보다는 한 함수로 합치는건 어떨까요?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그 리스너가 분리되어있습니다 입력되는 뷰가 달라서요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아하! 넹~~ |
||
|
||
private fun getInstalledApps() { | ||
viewModelScope.launch { | ||
val installApps = getInstalledAppUseCase() | ||
updateState { | ||
copy(installedApp = installApps) | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
완전 깔끔해졌다.!! 고마워 의진아 ^_<
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
굳~!!