1 /*
<lambda>null2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.deskclock.alarms
18 
19 import android.app.Dialog
20 import android.app.DialogFragment
21 import android.app.Fragment
22 import android.app.FragmentManager
23 import android.app.TimePickerDialog
24 import android.content.Context
25 import android.os.Bundle
26 import android.text.format.DateFormat
27 import android.widget.TimePicker
28 import androidx.appcompat.app.AlertDialog
29 
30 import com.android.deskclock.Utils
31 
32 import java.util.Calendar
33 
34 /**
35  * DialogFragment used to show TimePicker.
36  */
37 // TODO(b/157255731) Replace deprecated Fragment related calls with AndroidX equivalent
38 class TimePickerDialogFragment : DialogFragment() {
39 
40     override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
41         val listener = getParentFragment() as OnTimeSetListener
42 
43         val now = Calendar.getInstance()
44         val args: Bundle = if (getArguments() == null) Bundle.EMPTY else getArguments()
45         val hour: Int = args.getInt(ARG_HOUR, now[Calendar.HOUR_OF_DAY])
46         val minute: Int = args.getInt(ARG_MINUTE, now[Calendar.MINUTE])
47         return if (Utils.isLOrLater()) {
48             val context: Context = getActivity()
49             TimePickerDialog(context, { _, hourOfDay, minuteOfHour ->
50                 listener.onTimeSet(this@TimePickerDialogFragment, hourOfDay, minuteOfHour)
51             }, hour, minute, DateFormat.is24HourFormat(context))
52         } else {
53             val builder: AlertDialog.Builder = AlertDialog.Builder(getActivity())
54             val context: Context = builder.getContext()
55 
56             val timePicker = TimePicker(context)
57             timePicker.setCurrentHour(hour)
58             timePicker.setCurrentMinute(minute)
59             timePicker.setIs24HourView(DateFormat.is24HourFormat(context))
60 
61             builder.setView(timePicker)
62                     .setPositiveButton(android.R.string.ok, { _, _ ->
63                         listener.onTimeSet(this@TimePickerDialogFragment,
64                                 timePicker.getCurrentHour(), timePicker.getCurrentMinute())
65                     }).setNegativeButton(android.R.string.cancel, null /* listener */)
66                     .create()
67         }
68     }
69 
70     /**
71      * The callback interface used to indicate the user is done filling in the time (e.g. they
72      * clicked on the 'OK' button).
73      */
74     interface OnTimeSetListener {
75         /**
76          * Called when the user is done setting a new time and the dialog has closed.
77          *
78          * @param fragment the fragment associated with this listener
79          * @param hourOfDay the hour that was set
80          * @param minute the minute that was set
81          */
82         fun onTimeSet(fragment: TimePickerDialogFragment?, hourOfDay: Int, minute: Int)
83     }
84 
85     companion object {
86         /**
87          * Tag for timer picker fragment in FragmentManager.
88          */
89         private const val TAG = "TimePickerDialogFragment"
90 
91         private const val ARG_HOUR = TAG + "_hour"
92         private const val ARG_MINUTE = TAG + "_minute"
93 
94         @JvmStatic
95         fun show(fragment: Fragment) {
96             show(fragment, -1 /* hour */, -1 /* minute */)
97         }
98 
99         fun show(parentFragment: Fragment, hourOfDay: Int, minute: Int) {
100             require(parentFragment is OnTimeSetListener) {
101                 "Fragment must implement OnTimeSetListener"
102             }
103 
104             val manager: FragmentManager = parentFragment.getChildFragmentManager()
105             if (manager == null || manager.isDestroyed()) {
106                 return
107             }
108 
109             // Make sure the dialog isn't already added.
110             removeTimeEditDialog(manager)
111 
112             val fragment = TimePickerDialogFragment()
113 
114             val args = Bundle()
115             if (hourOfDay in 0..23) {
116                 args.putInt(ARG_HOUR, hourOfDay)
117             }
118             if (minute in 0..59) {
119                 args.putInt(ARG_MINUTE, minute)
120             }
121 
122             fragment.setArguments(args)
123             fragment.show(manager, TAG)
124         }
125 
126         @JvmStatic
127         fun removeTimeEditDialog(manager: FragmentManager?) {
128             manager?.let { manager ->
129                 val prev: Fragment? = manager.findFragmentByTag(TAG)
130                 prev?.let {
131                     manager.beginTransaction().remove(it).commit()
132                 }
133             }
134         }
135     }
136 }