Skip to content
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

#42 [feat] 데일리 루틴 #45

Merged
merged 22 commits into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
1a0c935
#42 [ui] 데일리 루틴 xml 코드 수정
emjayMJkim Jan 12, 2024
0aa97ec
#42 [mod] 데일리 루틴 삭제 xml 수정
emjayMJkim Jan 12, 2024
525e7be
#42 [add] 편집 버튼 클릭시 삭제 ui 띄우기
emjayMJkim Jan 12, 2024
bf72621
#42 [add] 데일리 루틴 더미 리스트 생성
emjayMJkim Jan 12, 2024
f7af8f5
#42 [ui] 데일리 루틴 리스트 ui 생성
emjayMJkim Jan 12, 2024
e73fe23
#42 [add] 삭제 버튼 selector 구현
emjayMJkim Jan 12, 2024
70a853d
#42 [feat] 각 아이템 삭제 버튼 클릭시 버튼에 삭제 개수 띄우기
emjayMJkim Jan 12, 2024
1da0c81
#42 [mod] 데일리 루틴 리스트 로직 수정
emjayMJkim Jan 12, 2024
72ed97c
#42 [ui] 데일리 루틴 xml 수정
emjayMJkim Jan 12, 2024
517f3c3
#42 [add] 버튼 클릭 시 바텀시트 띄우기
emjayMJkim Jan 12, 2024
eb4a269
#42 [mod] 공통 바텀시트 text color 코드 수정
emjayMJkim Jan 12, 2024
62b4299
#42 [ui] 기본 스낵바 띄우기
emjayMJkim Jan 12, 2024
5b6f0ac
#42 [fix] CI 오류 해결
emjayMJkim Jan 13, 2024
fbfa26b
#42 [fix] merge conflict 해결
emjayMJkim Jan 13, 2024
b19d3fd
#42 [feat] 데일리 루틴 달성 버튼 초기화
emjayMJkim Jan 13, 2024
a649272
#42 [ui] 완료하기 버튼 클릭시 바텀시트 띄우기
emjayMJkim Jan 13, 2024
be616ae
#42 [ui] 완료하기 버튼 클릭시 달성 토스트 띄우기
emjayMJkim Jan 14, 2024
76780a9
#42 [fix] CI 오류 해결
emjayMJkim Jan 14, 2024
30f49d5
#42 [feat] Custom snackbar 생성
emjayMJkim Jan 14, 2024
535652b
#42 [mod] snackbar 위치 조정 & 편집 전으로 돌아가기
emjayMJkim Jan 14, 2024
93f19a3
#42 [fix] merge conflict 해결
emjayMJkim Jan 14, 2024
39f90c8
#42 [mod] 코드 리뷰 반영 코드 수정
emjayMJkim Jan 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@
android:exported="false"
android:screenOrientation="portrait" />

<activity
android:name=".ui.dailyroutine.dailyroutineedit.DailyRoutineEditActivity"
android:exported="false"
android:screenOrientation="portrait" />

<activity
android:name=".ui.storytelling.StoryTellingActivity"
android:exported="false"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.sopetit.softie.domain.entity

data class DailyRoutine(
val routineId: Int,
val content: String,
val iconImageUrl: String,
val achieveCount: Int,
val isAchieve: Boolean
)
Original file line number Diff line number Diff line change
@@ -1,32 +1,176 @@
package com.sopetit.softie.ui.dailyroutine

import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.TextView
import androidx.fragment.app.viewModels
import com.sopetit.softie.R
import com.sopetit.softie.databinding.FragmentDailyRoutineBinding
import com.sopetit.softie.ui.dailyroutine.dailyroutineedit.DailyRoutineEditActivity
import com.sopetit.softie.util.OriginalBottomSheet.Companion.BOTTOM_SHEET_TAG
import com.sopetit.softie.util.binding.BindingBottomSheet
import com.sopetit.softie.util.binding.BindingFragment
import com.sopetit.softie.util.snackBar
import com.sopetit.softie.util.toast

class DailyRoutineFragment :
BindingFragment<FragmentDailyRoutineBinding>(R.layout.fragment_daily_routine) {

private val dailyRoutineViewModel by viewModels<DailyRoutineViewModel>()
private val viewModel by viewModels<DailyRoutineViewModel>()

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

binding.lifecycleOwner = this
binding.dailyRoutineViewModel = dailyRoutineViewModel
binding.viewModel = viewModel

moveEdit()
initSetDailyRoutineContent()
initSetDeleteView()
initSetRoutineDelete()
}

private fun moveEdit() {
binding.tvDailyRoutineEdit.setOnClickListener {
val intent = Intent(requireActivity(), DailyRoutineEditActivity::class.java)
startActivity(intent)
private fun initSetDailyRoutineContent() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드가 직관적이여서 이해하기 쉽고 좋아요^^

with(binding) {
routineItemView(
tvDailyRoutineAddNameFirst,
tvDailyRoutineIngFirst,
btnDailyRoutineYetFinFirst,
0
)
routineItemView(
tvDailyRoutineAddNameSecond,
tvDailyRoutineIngSecond,
btnDailyRoutineYetFinSecond,
1
)
routineItemView(
tvDailyRoutineAddNameThird,
tvDailyRoutineIngThird,
btnDailyRoutineYetFinThird,
2
)
}
}

private fun routineItemView(
routineTitle: TextView,
achieveMsg: TextView,
btn: View,
index: Int
) {
viewModel.mockDailyRoutineList.observe(viewLifecycleOwner) { dailyRoutineList ->
val achieveCountMsg =
getString(R.string.daily_routine_ing).format(dailyRoutineList[index].achieveCount)
achieveMsg.text = achieveCountMsg
routineTitle.text = dailyRoutineList[index].content
viewModel.setRoutineAchieve(dailyRoutineList[index].isAchieve, index)

initSetDailyRoutineAchieve(btn, dailyRoutineList[index].routineId)
}
}

private fun initSetDailyRoutineAchieve(btn: View, routineId: Int) {
btn.setOnClickListener {
// TODO 서버통신 구현 후 imageUri 버전으로 수정

BindingBottomSheet.Builder().build(
isDrawable = true,
imageDrawable = R.drawable.ic_bear_face_crying,
imageUri = "",
title = "데일리 루틴을 완료했나요?",
content = "한 번 완료하면 이전으로 되돌릴 수 없어요",
isContentVisible = true,
contentColor = R.color.gray400,
backBtnContent = "아니, 아직이야!",
doBtnContent = "완료했어",
doBtnColor = R.drawable.shape_main1_fill_12_rect,
backBtnAction = {},
doBtnAction = {
binding.root.context.toast("$routineId")
}
).show(parentFragmentManager, BOTTOM_SHEET_TAG)
}
}

private fun initSetDeleteView() {
viewModel.isDeleteView.observe(viewLifecycleOwner) { isDeleteView ->
if (!isDeleteView) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if문 안에는 ! 연산자를 넣지 않는 것이 좋다고 합니다!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앗 네엡 수정하겠습니다!

binding.tvDailyRoutineEdit.setOnClickListener {
viewModel.setDeleteView(true)
}
}
}

initSetBackOriginalView()
}

private fun initSetBackOriginalView() {
viewModel.isDeleteView.observe(viewLifecycleOwner) { isDeleteView ->
if (isDeleteView) {
binding.tvDailyRoutineEdit.setOnClickListener {
viewModel.setDeleteView(false)
}
clickEditRadioBtn()
}
}
}

private fun clickEditRadioBtn() {
viewModel.mockDailyRoutineList.observe(viewLifecycleOwner) { routineList ->
with(binding) {
changeBtnSelectState(btnDailyRoutineRadioFirst, routineList[0].routineId)
changeBtnSelectState(btnDailyRoutineRadioSecond, routineList[1].routineId)
changeBtnSelectState(btnDailyRoutineRadioThird, routineList[2].routineId)
}
}
}

private fun changeBtnSelectState(button: View, itemId: Int) {
button.setOnClickListener {
it.isSelected = !it.isSelected
viewModel.setEditRoutineIdArray(itemId)
setDeleteRoutineBtnContent()
}
}

private fun setDeleteRoutineBtnContent() {
val editRoutineArraySize = viewModel.editRoutineIdArray.size
val deleteBtnContent =
getString(R.string.daily_routine_edit_delete).format(editRoutineArraySize)

if (editRoutineArraySize > 0) {
viewModel.setEditBtnEnabled(true)
} else {
viewModel.setEditBtnEnabled(false)
}

binding.btnDailyRoutineDelete.text = deleteBtnContent
}

private fun initSetRoutineDelete() {
viewModel.isEditBtnEnabled.observe(viewLifecycleOwner) { isBtnEnabled ->
if (isBtnEnabled) {
binding.btnDailyRoutineDelete.setOnClickListener {
BindingBottomSheet.Builder().build(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Builder( )함수는 어떤 역할을 하나요??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

builder 패턴은 필요한 parameter만 설정해두면 build 메소드를 통해 객체를 생성할 수 있습니다..! 여기서 제가 공통 바텀시트를 만들어 두어서 이 builder 패턴을 통해서 각 뷰에서 커스텀되는 parameter만 넣어주면 바텀시트를 생성할 수 있습니다!!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

빌더 패턴까지 사용하시다니 정말 대단하군요 디자인패턴 공부 많이 한게 느껴졌어요. 저희꺼 바텀시트도 빌더로 만들어주세요 !!

isDrawable = true,
imageDrawable = R.drawable.ic_bear_face_crying,
imageUri = "",
title = "정말 삭제할까요?",
content = "루틴을 삭제해도 달성 횟수는 저장돼요",
isContentVisible = true,
contentColor = R.color.red,
backBtnContent = "취소",
doBtnContent = "삭제할래",
doBtnColor = R.drawable.shape_red_fill_12_rect,
backBtnAction = {},
doBtnAction = {
snackBar(
binding.root.rootView,
"데일리 루틴을 ${viewModel.editRoutineIdArray.size}개 삭제했어요"
)
viewModel.setDeleteView(false)
}
).show(parentFragmentManager, BOTTOM_SHEET_TAG)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,84 @@
package com.sopetit.softie.ui.dailyroutine

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.sopetit.softie.domain.entity.DailyRoutine

class DailyRoutineViewModel : ViewModel() {
val routineAddList = listOf<Int>(1, 2)

private val _mockDailyRoutineList: MutableLiveData<List<DailyRoutine>> = MutableLiveData(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

목데이터라도 잘 짜놓을껄...

mutableListOf(
DailyRoutine(
1,
"일찍 일어나기",
"",
3,
true
),
DailyRoutine(
2,
"작업 끝내기",
"",
5,
false
),
DailyRoutine(
3,
"이불 개기",
"",
10,
true
)
)
)

val mockDailyRoutineList: LiveData<List<DailyRoutine>>
get() = _mockDailyRoutineList

private val _isRoutineAchieveFirst: MutableLiveData<Boolean> = MutableLiveData()
val isRoutineAchieveFirst: LiveData<Boolean>
get() = _isRoutineAchieveFirst

private val _isRoutineAchieveSecond: MutableLiveData<Boolean> = MutableLiveData()
val isRoutineAchieveSecond: LiveData<Boolean>
get() = _isRoutineAchieveSecond

private val _isRoutineAchieveThird: MutableLiveData<Boolean> = MutableLiveData()
val isRoutineAchieveThird: LiveData<Boolean>
get() = _isRoutineAchieveThird

private val _isDeleteView: MutableLiveData<Boolean> = MutableLiveData(false)
val isDeleteView: LiveData<Boolean>
get() = _isDeleteView

val editRoutineIdArray = ArrayList<Int>()

private val _isEditBtnEnabled: MutableLiveData<Boolean> = MutableLiveData()
val isEditBtnEnabled: LiveData<Boolean>
get() = _isEditBtnEnabled

fun setRoutineAchieve(isAchieve: Boolean, index: Int) {
when (index) {
0 -> _isRoutineAchieveFirst.value = isAchieve
1 -> _isRoutineAchieveSecond.value = isAchieve
2 -> _isRoutineAchieveThird.value = isAchieve
}
}

fun setDeleteView(deleteEnabled: Boolean) {
_isDeleteView.value = deleteEnabled
}

fun setEditRoutineIdArray(routineId: Int) {
if (editRoutineIdArray.contains(routineId)) {
editRoutineIdArray.removeAt(editRoutineIdArray.indexOf(routineId))
} else {
editRoutineIdArray.add(routineId)
}
}

fun setEditBtnEnabled(enabled: Boolean) {
_isEditBtnEnabled.value = enabled
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.sopetit.softie.R
import com.sopetit.softie.databinding.FragmentSettingInitBinding
import com.sopetit.softie.ui.setting.SettingActivity.Companion.USER_EXIT
import com.sopetit.softie.ui.setting.SettingActivity.Companion.USER_SECURITY
import com.sopetit.softie.util.OriginalBottomSheet.Companion.BOTTOM_SHEET_TAG
import com.sopetit.softie.util.binding.BindingBottomSheet
import com.sopetit.softie.util.binding.BindingFragment

Expand Down Expand Up @@ -73,7 +74,7 @@ class SettingInitFragment :
}
}

companion object {
const val BOTTOM_SHEET_TAG = "BOTTOM SHEET TAG"
}
// companion object {
// const val BOTTOM_SHEET_TAG = "BOTTOM SHEET TAG"
// }
}
3 changes: 1 addition & 2 deletions app/src/main/java/com/sopetit/softie/util/Context.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import android.content.Context
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import com.google.android.material.snackbar.Snackbar

fun Context.hideKeyboard(view: View) {
val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
Expand All @@ -16,7 +15,7 @@ fun snackBar(
anchorView: View,
message: String,
) {
Snackbar.make(anchorView, message, Snackbar.LENGTH_SHORT).show()
CustomSnackbar.make(anchorView, message).show()
}

fun Context.toast(message: String) {
Expand Down
Loading