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

DEP-204 feat: 30분 간격인 timepicker 제작 #75

Merged
merged 5 commits into from
Dec 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions core-design-system/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,11 @@
<style name="RoundCornerModalStyle" parent="Widget.Design.BottomSheet.Modal">
<item name="android:background">@drawable/bg_rect_white_top_r20</item>
</style>

<style name="ThreeDaysTimePickerTheme" parent="Theme.AppCompat.Light">
<item name="android:colorControlNormal">@color/gray_400</item>
<item name="android:textSize">17sp</item>
<item name="android:textColorPrimary">@color/gray_800</item>
<item name="android:textAppearance">@style/Typography.Body1</item>
</style>
</resources>
2 changes: 2 additions & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ dependencies {
implementation deps.hilt.core
kapt deps.hilt.compiler

implementation deps.timber

testImplementation(testDeps)
androidTestImplementation(androidTestDeps)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.depromeet.threedays.core.extensions

import java.time.LocalTime
import java.time.format.DateTimeFormatter

fun LocalTime.formatWithPattern(pattern: String): String {
return this.format(DateTimeFormatter.ofPattern(pattern))
kimhyeing marked this conversation as resolved.
Show resolved Hide resolved
}

fun LocalTime.formatHourMinute(): String {
return this.format(DateTimeFormatter.ofPattern("HH:mm"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.depromeet.threedays.core.util

import android.content.res.Resources
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.NumberPicker
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.DialogFragment
import com.depromeet.threedays.core.R
import com.depromeet.threedays.core.databinding.FragmentRangeTimePickerDialogBinding
import com.depromeet.threedays.core.setOnSingleClickListener
import java.time.LocalTime

class RangeTimePickerDialogFragment : DialogFragment() {
private var _binding: FragmentRangeTimePickerDialogBinding? = null
private val binding get() = _binding!!

private var time = LocalTime.now()
private lateinit var onConfirmClickListener: (time: LocalTime) -> Unit

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_range_time_picker_dialog,
container,
false
)
binding.lifecycleOwner = viewLifecycleOwner

return binding.root
}

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

setLayout()
initView()
setTimePicker()
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}

private fun setLayout() {
requireNotNull(dialog).apply {
requireNotNull(window).apply {
setBackgroundDrawableResource(com.depromeet.threedays.core_design_system.R.drawable.bg_rect_white_r18)
}
}
}

private fun initView() {
binding.timePicker.hour = time.hour
binding.timePicker.minute = time.minute / TIME_PICKER_INTERVAL_MINUTE

binding.tvCancel.setOnSingleClickListener { dismiss() }

binding.tvConfirm.setOnSingleClickListener {
onConfirmClickListener.invoke(
LocalTime.of(binding.timePicker.hour, binding.timePicker.minute * TIME_PICKER_INTERVAL_MINUTE)
)
dismiss()
}
}

private fun setTimePicker() {
(binding.timePicker.findViewById(
Resources.getSystem().getIdentifier("minute", "id", "android")
) as NumberPicker).apply {
minValue = 0
maxValue = 60 / TIME_PICKER_INTERVAL_MINUTE - 1
displayedValues = getDisplayedValue().toTypedArray()
setOnValueChangedListener(null)
}
}

private fun getDisplayedValue(
): MutableList<String> {
val displayedValues: MutableList<String> = java.util.ArrayList()
for (i in 0..59 step TIME_PICKER_INTERVAL_MINUTE)
displayedValues.add(String.format("%02d", i))
return displayedValues
}

companion object {
const val TAG = "RangeTimePickerDialogFragment"

const val TIME_PICKER_INTERVAL_MINUTE = 30

fun newInstance(
time: LocalTime, onConfirmClickListener: (time: LocalTime) -> Unit
): RangeTimePickerDialogFragment {
val fragment = RangeTimePickerDialogFragment()
fragment.time = time
fragment.onConfirmClickListener = onConfirmClickListener
return fragment
}
}
}
70 changes: 70 additions & 0 deletions core/src/main/res/layout/fragment_range_time_picker_dialog.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<data>

</data>

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context=".util.RangeTimePickerDialogFragment">

<TimePicker
android:id="@+id/time_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="3dp"
android:paddingHorizontal="10dp"
android:theme="@style/ThreeDaysTimePickerTheme"
android:timePickerMode="spinner"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<View
android:id="@+id/divider"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="@color/gray_200"
app:layout_constraintEnd_toEndOf="@+id/time_picker"
app:layout_constraintStart_toStartOf="@+id/time_picker"
app:layout_constraintTop_toBottomOf="@+id/time_picker" />

<TextView
android:id="@+id/tv_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingVertical="22dp"
android:text="@string/cancel"
android:textAppearance="@style/Typography.Body1"
app:layout_constraintEnd_toStartOf="@+id/tv_confirm"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/divider" />

<View
android:id="@+id/divider_button"
android:layout_width="1dp"
android:layout_height="0dp"
android:background="@color/gray_200"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/tv_confirm"
app:layout_constraintStart_toEndOf="@+id/tv_cancel"
app:layout_constraintTop_toBottomOf="@+id/time_picker" />

<TextView
android:id="@+id/tv_confirm"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:text="@string/confirm"
android:textAppearance="@style/Typography.Body1"
app:layout_constraintBottom_toBottomOf="@+id/tv_cancel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_cancel"
app:layout_constraintTop_toTopOf="@+id/tv_cancel" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
2 changes: 2 additions & 0 deletions core/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@
<string name="toast_habit_delete_complete">습관이 삭제됐어요.</string>
<string name="toast_habit_modify_complete">습관이 수정됐어요.</string>
<string name="toast_app_alarm_on_complete">앱 알림이 켜졌어요.</string>
<string name="cancel">취소</string>
<string name="confirm">확인</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@ import android.widget.EditText
import androidx.activity.viewModels
import androidx.core.widget.addTextChangedListener
import com.depromeet.threedays.core.BaseActivity
import com.depromeet.threedays.core.extensions.formatHourMinute
import com.depromeet.threedays.core.extensions.visibleOrGone
import com.depromeet.threedays.core.setOnSingleClickListener
import com.depromeet.threedays.core.util.Emoji
import com.depromeet.threedays.core.util.RangeTimePickerDialogFragment
import com.depromeet.threedays.create.R
import com.depromeet.threedays.create.databinding.ActivityHabitCreateBinding
import com.depromeet.threedays.create.emoji.EmojiBottomSheetDialogFragment
import dagger.hilt.android.AndroidEntryPoint
import java.time.LocalTime

@AndroidEntryPoint
class HabitCreateActivity : BaseActivity<ActivityHabitCreateBinding>(R.layout.activity_habit_create) {
class HabitCreateActivity :
BaseActivity<ActivityHabitCreateBinding>(R.layout.activity_habit_create) {
private val viewModel by viewModels<HabitCreateViewModel>()

override fun onCreate(savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -62,49 +66,22 @@ class HabitCreateActivity : BaseActivity<ActivityHabitCreateBinding>(R.layout.ac

binding.tvEmoji.text = Emoji().getEmojiString(Emoji.Word.FIRE)
binding.tvEmoji.setOnSingleClickListener {
EmojiBottomSheetDialogFragment.newInstance {
emojiString -> run { binding.tvEmoji.text = emojiString }
EmojiBottomSheetDialogFragment.newInstance { emojiString ->
run { binding.tvEmoji.text = emojiString }
}.show(supportFragmentManager, EmojiBottomSheetDialogFragment.TAG)
}
}

/*
private fun observe() {
viewModel.action.onEach { action ->
when (action) {
is SaveClick -> {
setResult(RESULT_CREATE)
finish()
}
}
}.launchIn(lifecycleScope)
binding.tvNotificationTime.setOnSingleClickListener {
showTimePicker()
}
}


private fun showTimePicker(zonedDateTime: ZonedDateTime, isRunTime: Boolean) {
val timeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, min ->
if (isRunTime) {
viewModel.setStartTime(hour, min)
binding.tvRunTime.text = getTimeFormat(hour, min)
if(viewModel.goal.value.notificationTime == null) {
viewModel.setNotificationTime(hour, min)
binding.tvNotification.text = getTimeFormat(hour, min)
}
} else {
viewModel.setNotificationTime(hour, min)
binding.tvNotification.text = getTimeFormat(hour, min)
private fun showTimePicker() {
RangeTimePickerDialogFragment.newInstance(
time = LocalTime.now(),
onConfirmClickListener = { time ->
binding.tvNotificationTime.text = time.formatHourMinute()
}
}
val dialog = TimePickerDialog(
this,
android.R.style.Theme_Holo_Light_Dialog_NoActionBar,
timeSetListener,
zonedDateTime.hour,
zonedDateTime.minute,
false
)
dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
dialog.show()
).show(supportFragmentManager, RangeTimePickerDialogFragment.TAG)
}
*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ import android.widget.EditText
import androidx.activity.viewModels
import androidx.core.widget.addTextChangedListener
import com.depromeet.threedays.core.BaseActivity
import com.depromeet.threedays.core.extensions.formatHourMinute
import com.depromeet.threedays.core.extensions.visibleOrGone
import com.depromeet.threedays.core.setOnSingleClickListener
import com.depromeet.threedays.core.util.Emoji
import com.depromeet.threedays.core.util.RangeTimePickerDialogFragment
import com.depromeet.threedays.create.R
import com.depromeet.threedays.create.databinding.ActivityHabitUpdateBinding
import com.depromeet.threedays.create.emoji.EmojiBottomSheetDialogFragment
import dagger.hilt.android.AndroidEntryPoint
import java.time.LocalTime

@AndroidEntryPoint
class HabitUpdateActivity : BaseActivity<ActivityHabitUpdateBinding>(R.layout.activity_habit_update) {
Expand Down Expand Up @@ -66,44 +69,18 @@ class HabitUpdateActivity : BaseActivity<ActivityHabitUpdateBinding>(R.layout.ac
emojiString -> run { binding.tvEmoji.text = emojiString }
}.show(supportFragmentManager, EmojiBottomSheetDialogFragment.TAG)
}
}

/*
private fun observe() {
viewModel.action.onEach { action ->
when (action) {
is UpdateClick -> {
setResult(RESULT_MODIFY)
finish()
}
}
}.launchIn(lifecycleScope)
binding.tvNotificationTime.setOnSingleClickListener {
showTimePicker()
}
}

private fun showTimePicker(zonedDateTime: ZonedDateTime, isRunTime: Boolean) {
val timeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, min ->
if (isRunTime) {
viewModel.setStartTime(hour, min)
binding.tvRunTime.text = getTimeFormat(hour, min)
if(viewModel.goal.value.notificationTime == null) {
viewModel.setNotificationTime(hour, min)
binding.tvNotification.text = getTimeFormat(hour, min)
}
} else {
viewModel.setNotificationTime(hour, min)
binding.tvNotification.text = getTimeFormat(hour, min)
private fun showTimePicker() {
RangeTimePickerDialogFragment.newInstance(
time = LocalTime.now(),
onConfirmClickListener = { time ->
binding.tvNotificationTime.text = time.formatHourMinute()
}
}
val dialog = TimePickerDialog(
this,
android.R.style.Theme_Holo_Light_Dialog_NoActionBar,
timeSetListener,
zonedDateTime.hour,
zonedDateTime.minute,
false
)
dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
dialog.show()
).show(supportFragmentManager, RangeTimePickerDialogFragment.TAG)
}
*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@
android:layout_marginEnd="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/tv_notification"
app:layout_constraintTop_toBottomOf="@+id/tv_notification">
app:layout_constraintTop_toBottomOf="@+id/sw_notification">

<TextView
android:id="@+id/tv_notification_time"
Expand Down
Loading