-
Notifications
You must be signed in to change notification settings - Fork 0
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
Feat : 학사 일정 데이트 피커 #263
base: develop
Are you sure you want to change the base?
Feat : 학사 일정 데이트 피커 #263
Conversation
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.
코멘트 확인 부탁드려요! 로직을 한 번 더 생각해보시면 좋을 것 같습니다! MVVM을 사용하면 충분히 구현할 수 있을 것 같아용
class DatePickerDialog( | ||
val year: Int, | ||
val month: Int, | ||
private val dateSelectedListener: ScheduleFragment, |
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.
다이얼로그를 생성할 때 생성자로 fragment를 꼭 받아야 할까요?? 프래그먼트를 생성자로 받지 않고 다른 방법으로 구현해보시면 좋을 것 같아요 👍
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.
이전에 Dialog를 사용한 부분에서 가져온거라 생각을 못해봤네요 수정해보겠습니다
interface OnDateSelectedListener { | ||
fun onDateSelected(year: Int, month: Int) | ||
} | ||
|
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.
인터페이스를 분리하면 좋을 것 같아요 👍
private var _year = LocalDate.now().year.toString() | ||
private var year = _year | ||
|
||
private var _month = LocalDate.now().month.toString() | ||
private var month = _month |
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.
둘 다 접근제한자가 private인데 프래그먼트에서 배킹프로퍼티를 사용하는 이유가 있나요 ?
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.
기존 코드들을 참고하여서 배킹 프로퍼티의 의미를 제대로 생각 못한거 같습니다🤔
코드를 다시 살펴본 후 명확히 답변 드리곘습니다.
private var _binding: DialogDatepickerBinding? = null | ||
private val binding get() = _binding!! | ||
|
||
private val viewModel: ScheduleViewModel by viewModel() |
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.
학사일정 프래그먼트와 뷰모델을 공유하려면 activityViewModels를 쓰면 될 것 같아요! 따로 다이얼로그에서 뷰모델 인스턴스를 새로 생성하는 이유가 있나요?
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.
코드를 살펴보니 별도의 인스턴스를 생성할 이유가 없네요..
익숙한 코드를 사용하여 생각해보지 못한 부분이라 말씀하신 대로 activityViewModels로 수정하겠습니다.
month = month.toInt(), | ||
dateSelectedListener = this | ||
) | ||
dialog.show(requireActivity().supportFragmentManager, "CustomDialog") |
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.
Tag 값은 상수화해서 사용하는 게 좋을 것 같아요! 그리고 커스텀 다이얼로그 보다는 다른 네이밍을 사용하면 좋을 것 같습니당
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.
requireActivity
와 requireContext
의 차이가 무엇일까요! 어디에는 위에서 컬러값을 가져올 땐 requireContext
를 사용하셨는데 요기선 requireActivity
를 사용하신 이유가 궁금해용
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.
dialog Manager
에서만 사용하는 부분으로 중요하다고 생각을 못하여 네이밍을 크게 신경쓰지 못했네요.
ScheduleDialog
정도로 수정 후 Tag 상수화를 사용하겠습니다.
requireActivity
액티비티 반환으로 activity!!
와 동일한 작용으로 알고있습니다.
dialog
의 activity
상속 개념으로 인하여 사용한 부분입니다.
requireContext
는 컬러 리소스값에 접근해야하기에 Context
를 사용합니다.
getContext
와 달리 null
값이 아닌 context
를 필수적으로 전달한다고 하여 사용했습니다.
requireContext
는 null 처리가 되지 않아 코드 확인 후 getContext
사용과 requireContext
중 뭐가 더 나을지 고민해보겠습니다.
|
||
private val viewModel: ScheduleViewModel by viewModel() | ||
|
||
override fun onCreateView( |
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.
fragment의 생명주기에 대해서 알고 계신가요 ? onCreateView
에서 해야할 일과 onViewCreated
에서 해야할 일을 분리하면 좋을 것 같슴니다
참고할 블로그
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.
이전에 타프로젝트에서 언급주셨던 부분이라 기억하고 있습니다.
로직 변경을 하면서 고려해보겠습니다.
// 현재 연도 | ||
val currentYear = LocalDate.now().year | ||
|
||
// 순환 막기 | ||
binding.numberpickerDialogDatepickerYear.wrapSelectorWheel = false | ||
binding.numberpickerDialogDatepickerMonth.wrapSelectorWheel = false | ||
|
||
// editText 설정 막기 | ||
binding.numberpickerDialogDatepickerYear.descendantFocusability = | ||
NumberPicker.FOCUS_BLOCK_DESCENDANTS | ||
binding.numberpickerDialogDatepickerMonth.descendantFocusability = | ||
NumberPicker.FOCUS_BLOCK_DESCENDANTS | ||
|
||
// 연도 최소/최대값 설정 및 출력 방식 설정 | ||
with(binding.numberpickerDialogDatepickerYear) { | ||
minValue = currentYear - 1 | ||
maxValue = currentYear + 1 | ||
displayedValues=((minValue..maxValue).map{"$it 년"}.toTypedArray()) | ||
} | ||
|
||
// 월 최소/최대값 설정 및 출력 방식 설정 | ||
with(binding.numberpickerDialogDatepickerMonth) { | ||
minValue = 1 | ||
maxValue = if (year == currentYear + 1) 2 else 12 | ||
|
||
// 연도 선택에 따른 월의 최대값 동적 설정 | ||
binding.numberpickerDialogDatepickerYear.setOnValueChangedListener { _, _, newYear -> | ||
maxValue = if (newYear == currentYear + 1) 2 else 12 | ||
} | ||
|
||
displayedValues=((minValue..maxValue).map{"$it 월"}.toTypedArray()) | ||
} | ||
|
||
// 초기 설정 | ||
binding.numberpickerDialogDatepickerYear.value = year | ||
binding.numberpickerDialogDatepickerMonth.value = month | ||
|
||
binding.tvDialogPermissionComplete.setOnClickListener { | ||
viewModel.setDatePicker( | ||
binding.numberpickerDialogDatepickerYear.value, | ||
binding.numberpickerDialogDatepickerMonth.value | ||
) | ||
dateSelectedListener.onDateSelected( | ||
binding.numberpickerDialogDatepickerYear.value, | ||
binding.numberpickerDialogDatepickerMonth.value | ||
) | ||
dismiss() | ||
} | ||
|
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.
메서드를 분리하면 가독성이 더 좋아질 것 같아욥
app/src/main/java/com/dongyang/android/youdongknowme/ui/view/schedule/DatePickerDialog.kt
Outdated
Show resolved
Hide resolved
app/src/main/java/com/dongyang/android/youdongknowme/ui/view/schedule/DatePickerDialog.kt
Show resolved
Hide resolved
dateSelectedListener.onDateSelected( | ||
binding.numberpickerDialogDatepickerYear.value, | ||
binding.numberpickerDialogDatepickerMonth.value | ||
) |
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.
MVVM 패턴을 사용하면 이 로직은 없어도 될 것 같아요. 현재 상태는 다이얼로그에서 선택한 값을 fragment로 직접 넘기는 형태이고 뷰모델을 사용하지 않는 것 같습니다! 뷰모델을 사용해서 dialog 의 생성자 중 fragment 를 제거하고, fragment에서도 interface 를 제거하고, 뷰모델에서 observe 받은 값으로만 수정해도 될 것 같아요
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.
Dialog 구현에 앞서 MVVM 형태의 로직을 고려를 제대로 못하고 익숙한 방식으로 진행한거 같습니다.
로직을 수정해보겠습니다.
ea5394b
to
7e4ab80
Compare
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.
MVVM 로직 구조에 대해서 다시 답변드렸습니다!
코멘트 확인 부탁드려용
_binding = DialogDatepickerBinding.inflate(inflater, container, false) | ||
val view = binding.root |
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.
뷰바인딩을 초기화하고 반환 이후에 binding 객체를 사용하는 게 더 안전해보입니다!
// 초기 설정 | ||
binding.numberpickerDialogDatepickerYear.value = year | ||
binding.numberpickerDialogDatepickerMonth.value = month | ||
|
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.
초기값을 설정하는 건 onCreateView에서의 역할이 아닌 것 같습니다! 뷰바인딩이 세팅이 끝난 후인 onViewCreated로 옮겨보시죵
private val year: Int, | ||
private val month: Int, | ||
private val listener: ScheduleClickListener |
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.
생성자로 연도, 월, 클릭리스너를 받아야 할까요?
binding.tvDialogPermissionComplete.setOnClickListener { | ||
val year = binding.numberpickerDialogDatepickerYear.value | ||
val month = binding.numberpickerDialogDatepickerMonth.value | ||
val date = CalendarDay.from(year, month, 1) | ||
|
||
listener.buttonClick(date = date) | ||
|
||
dismiss() |
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.
지금 방법은 MVVM 패턴이 아닌 것 같습니다! view 변경 시 ViewModel 내 메서드 호출 > fragment 에서 viewModel의 파라미터 observing > 학사일정 변경
이 로직대로 가야 할 것 같아요! 지금 로직은 interface로 직접 값을 넘기는 것 같습니다.
|
||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { | ||
|
||
return BottomSheetDialog(requireContext(), R.style.CustomBottomSheetDialogTheme) |
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.
이 친구는 onCreateView에서 작동을 안 하나요 ?
onCreateView에
setStyle(STYLE_NORMAL, R.style.WebsosoDialogTheme)
요 코드 넣어보시면 될 거예요
interface ScheduleClickListener { | ||
fun buttonClick(date: CalendarDay) | ||
} |
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.
인터페이스를 제거해보시죠!
override fun buttonClick(date: CalendarDay) { | ||
viewModel.setPickedDate(date) | ||
} |
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.
이 인터페이스를 만들지 않고, 다이얼로그에서 버튼을 클릭했을 때 viewModel.setPickedDate 를 사용하면 될 것 같아요
📮 관련 이슈
✍️ 구현 내용
📷 구현 영상
date-picker.mp4
✔️ 확인 사항