Skip to content

Commit ab66085

Browse files
committed
refactor onClick and onAttachedWindow
1 parent a69fa2f commit ab66085

File tree

1 file changed

+183
-179
lines changed

1 file changed

+183
-179
lines changed

android/src/main/java/com/reactcommunity/rndatetimepicker/CustomTimePickerDialog.java

Lines changed: 183 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import java.util.ArrayList;
44
import java.util.List;
5-
import java.util.Locale;
65

76
import android.app.TimePickerDialog;
87
import android.content.DialogInterface;
@@ -14,206 +13,211 @@
1413
import android.widget.NumberPicker;
1514

1615
class CustomTimePickerDialog extends TimePickerDialog {
17-
private static final String LOG_TAG = CustomTimePickerDialog.class.getSimpleName();
18-
19-
private TimePicker mTimePicker;
20-
private int mTimePickerInterval;
21-
private RNTimePickerDisplay mDisplay;
22-
private final OnTimeSetListener mTimeSetListener;
23-
private Handler handler = new Handler();
24-
private Runnable runnable;
25-
private Context mContext;
26-
27-
public CustomTimePickerDialog(
28-
Context context,
29-
OnTimeSetListener listener,
30-
int hourOfDay,
31-
int minute,
32-
int minuteInterval,
33-
boolean is24HourView,
34-
RNTimePickerDisplay display
35-
) {
36-
super(context, listener, hourOfDay, minute, is24HourView);
37-
mTimePickerInterval = minuteInterval;
38-
mTimeSetListener = listener;
39-
mDisplay = display;
40-
mContext = context;
41-
}
42-
43-
public CustomTimePickerDialog(
44-
Context context,
45-
int theme,
46-
OnTimeSetListener listener,
47-
int hourOfDay,
48-
int minute,
49-
int minuteInterval,
50-
boolean is24HourView,
51-
RNTimePickerDisplay display
52-
) {
53-
super(context, theme, listener, hourOfDay, minute, is24HourView);
54-
mTimePickerInterval = minuteInterval;
55-
mTimeSetListener = listener;
56-
mDisplay = display;
57-
mContext = context;
58-
}
59-
60-
/**
61-
* Converts values returned from picker to actual minutes
62-
*
63-
* @param minute the internal value of what the user had selected on picker
64-
* @return returns 'real' minutes (0-59)
65-
*/
66-
private int getRealMinutes(int minute) {
67-
if (mDisplay == RNTimePickerDisplay.SPINNER) {
68-
return minute * mTimePickerInterval;
16+
private TimePicker mTimePicker;
17+
private int mTimePickerInterval;
18+
private RNTimePickerDisplay mDisplay;
19+
private final OnTimeSetListener mTimeSetListener;
20+
private Handler handler = new Handler();
21+
private Runnable runnable;
22+
private Context mContext;
23+
24+
public CustomTimePickerDialog(
25+
Context context,
26+
OnTimeSetListener listener,
27+
int hourOfDay,
28+
int minute,
29+
int minuteInterval,
30+
boolean is24HourView,
31+
RNTimePickerDisplay display
32+
) {
33+
super(context, listener, hourOfDay, minute, is24HourView);
34+
mTimePickerInterval = minuteInterval;
35+
mTimeSetListener = listener;
36+
mDisplay = display;
37+
mContext = context;
6938
}
7039

71-
return minute;
72-
}
40+
public CustomTimePickerDialog(
41+
Context context,
42+
int theme,
43+
OnTimeSetListener listener,
44+
int hourOfDay,
45+
int minute,
46+
int minuteInterval,
47+
boolean is24HourView,
48+
RNTimePickerDisplay display
49+
) {
50+
super(context, theme, listener, hourOfDay, minute, is24HourView);
51+
mTimePickerInterval = minuteInterval;
52+
mTimeSetListener = listener;
53+
mDisplay = display;
54+
mContext = context;
55+
}
7356

74-
/**
75-
* 'Snaps' real minutes to nearest valid value
76-
*
77-
* @param realMinutes 'real' minutes (0-59)
78-
* @return nearest valid value
79-
*/
80-
private int snapMinutesToInterval(int realMinutes) {
81-
float stepsInMinutes = (float) realMinutes / (float) mTimePickerInterval;
57+
/**
58+
* Converts values returned from picker to actual minutes
59+
*
60+
* @param minute the internal value of what the user had selected on picker
61+
* @return returns 'real' minutes (0-59)
62+
*/
63+
private int getRealMinutes(int minute) {
64+
if (mDisplay == RNTimePickerDisplay.SPINNER) {
65+
return minute * mTimePickerInterval;
66+
}
8267

83-
if (mDisplay == RNTimePickerDisplay.SPINNER) {
84-
return Math.round(stepsInMinutes);
68+
return minute;
8569
}
8670

87-
return Math.round(stepsInMinutes) * mTimePickerInterval;
88-
}
89-
90-
/**
91-
* Determines if real minutes align setted minuteInterval
92-
*
93-
* @param realMinutes 'real' minutes (0-59)
94-
*/
95-
private boolean minutesAreInvalid(int realMinutes) {
96-
return realMinutes % mTimePickerInterval != 0;
97-
}
98-
99-
/**
100-
* Determines if the picker is in text input mode (keyboard icon in 'clock' mode)
101-
*/
102-
private boolean pickerIsInTextInputMode() {
103-
int textInputPickerId = mContext.getResources().getIdentifier("input_mode", "id", "android");
104-
final View textInputPicker = this.findViewById(textInputPickerId);
105-
106-
return textInputPicker != null && textInputPicker.hasFocus();
107-
}
108-
109-
/**
110-
* Corrects minute values if they don't align with minuteInterval
111-
*
112-
* If the picker is in text input mode, correction will be postponed slightly to let the user
113-
* finish the input
114-
*
115-
* If the picker is not in text input mode, correction will take place immidiately
116-
*
117-
* @param view the picker's view
118-
* @param hourOfDay the picker's selected hours
119-
* @param realMinutes 'real' minutes (0-59)
120-
*/
121-
private void correctEnteredMinutes(final TimePicker view, final int hourOfDay, final int realMinutes) {
122-
if (pickerIsInTextInputMode()) {
123-
final EditText textInput = (EditText) view.findFocus();
124-
125-
// 'correction' callback
126-
runnable = new Runnable() {
127-
@Override
128-
public void run() {
129-
// set valid minutes && move caret to the end of input
130-
view.setCurrentMinute(snapMinutesToInterval(realMinutes));
131-
view.setCurrentHour(hourOfDay);
132-
textInput.setSelection(textInput.getText().length());
71+
/**
72+
* 'Snaps' real minutes to nearest valid value
73+
*
74+
* @param realMinutes 'real' minutes (0-59)
75+
* @return nearest valid value
76+
*/
77+
private int snapMinutesToInterval(int realMinutes) {
78+
float stepsInMinutes = (float) realMinutes / (float) mTimePickerInterval;
79+
80+
if (mDisplay == RNTimePickerDisplay.SPINNER) {
81+
return Math.round(stepsInMinutes);
13382
}
134-
};
13583

136-
handler.postDelayed(runnable, 500);
137-
return;
84+
return Math.round(stepsInMinutes) * mTimePickerInterval;
13885
}
13986

140-
view.setCurrentMinute(snapMinutesToInterval(realMinutes));
141-
view.setCurrentHour(hourOfDay);
142-
}
87+
/**
88+
* Determines if real minutes align setted minuteInterval
89+
*
90+
* @param realMinutes 'real' minutes (0-59)
91+
*/
92+
private boolean minutesAreInvalid(int realMinutes) {
93+
return realMinutes % mTimePickerInterval != 0;
94+
}
14395

144-
@Override
145-
public void onTimeChanged(final TimePicker view, final int hourOfDay, final int minute) {
146-
final int realMinutes = getRealMinutes(minute);
96+
/**
97+
* Determines if the picker is in text input mode (keyboard icon in 'clock' mode)
98+
*/
99+
private boolean pickerIsInTextInputMode() {
100+
int textInputPickerId = mContext.getResources().getIdentifier("input_mode", "id", "android");
101+
final View textInputPicker = this.findViewById(textInputPickerId);
147102

148-
// remove pending 'validation' callbacks if any
149-
handler.removeCallbacks(runnable);
103+
return textInputPicker != null && textInputPicker.hasFocus();
104+
}
150105

151-
if (minutesAreInvalid(realMinutes)) {
152-
correctEnteredMinutes(view, hourOfDay, realMinutes);
153-
return;
106+
/**
107+
* Corrects minute values if they don't align with minuteInterval
108+
* <p>
109+
* If the picker is in text input mode, correction will be postponed slightly to let the user
110+
* finish the input
111+
* <p>
112+
* If the picker is not in text input mode, correction will take place immidiately
113+
*
114+
* @param view the picker's view
115+
* @param hourOfDay the picker's selected hours
116+
* @param realMinutes 'real' minutes (0-59)
117+
*/
118+
private void correctEnteredMinutes(final TimePicker view, final int hourOfDay, final int realMinutes) {
119+
if (pickerIsInTextInputMode()) {
120+
final EditText textInput = (EditText) view.findFocus();
121+
122+
// 'correction' callback
123+
runnable = new Runnable() {
124+
@Override
125+
public void run() {
126+
// set valid minutes && move caret to the end of input
127+
view.setCurrentMinute(snapMinutesToInterval(realMinutes));
128+
view.setCurrentHour(hourOfDay);
129+
textInput.setSelection(textInput.getText().length());
130+
}
131+
};
132+
133+
handler.postDelayed(runnable, 500);
134+
return;
135+
}
136+
137+
view.setCurrentMinute(snapMinutesToInterval(realMinutes));
138+
view.setCurrentHour(hourOfDay);
154139
}
155140

156-
super.onTimeChanged(view, hourOfDay, realMinutes);
157-
}
141+
@Override
142+
public void onTimeChanged(final TimePicker view, final int hourOfDay, final int minute) {
143+
final int realMinutes = getRealMinutes(minute);
158144

159-
@Override
160-
public void onClick(DialogInterface dialog, int which) {
161-
switch (which) {
162-
case BUTTON_POSITIVE:
163-
final int hours = mTimePicker.getCurrentHour();
164-
final int realMinutes = getRealMinutes(mTimePicker.getCurrentMinute());
165-
int minutesToCallListenerWith = realMinutes;
145+
// remove pending 'validation' callbacks if any
146+
handler.removeCallbacks(runnable);
166147

167-
if (pickerIsInTextInputMode() && minutesAreInvalid(realMinutes)) {
168-
minutesToCallListenerWith = snapMinutesToInterval(realMinutes);
148+
if (minutesAreInvalid(realMinutes)) {
149+
correctEnteredMinutes(view, hourOfDay, realMinutes);
150+
return;
169151
}
170152

171-
if (mTimeSetListener != null) {
172-
mTimeSetListener.onTimeSet(mTimePicker, hours, minutesToCallListenerWith);
173-
}
174-
break;
175-
case BUTTON_NEGATIVE:
176-
cancel();
177-
break;
153+
super.onTimeChanged(view, hourOfDay, realMinutes);
178154
}
179-
}
180-
181-
@Override
182-
public void updateTime(int hourOfDay, int minuteOfHour) {
183-
mTimePicker.setCurrentHour(hourOfDay);
184-
mTimePicker.setCurrentMinute(snapMinutesToInterval(minuteOfHour));
185-
}
186-
187-
/**
188-
* Apply visual style in 'spinner' mode
189-
* Adjust minutes to correspond selected interval
190-
*/
191-
@Override
192-
public void onAttachedToWindow() {
193-
super.onAttachedToWindow();
194-
195-
if (mTimePickerInterval > RNConstants.DEFAULT_TIME_PICKER_INTERVAL) {
196-
int timePickerId = mContext.getResources().getIdentifier("timePicker", "id", "android");
197-
198-
mTimePicker = this.findViewById(timePickerId);
199-
int currentMinute = mTimePicker.getCurrentMinute();
200-
201-
if (mDisplay == RNTimePickerDisplay.SPINNER) {
202-
int minutePickerId = mContext.getResources().getIdentifier("minute", "id", "android");
203-
NumberPicker minutePicker = this.findViewById(minutePickerId);
204-
205-
minutePicker.setMinValue(0);
206-
minutePicker.setMaxValue((60 / mTimePickerInterval) - 1);
207-
208-
List<String> displayedValues = new ArrayList<>();
209-
for (int i = 0; i < 60; i += mTimePickerInterval) {
210-
displayedValues.add(String.format("%02d", i));
155+
156+
@Override
157+
public void onClick(DialogInterface dialog, int which) {
158+
if (mTimePickerInterval == RNConstants.DEFAULT_TIME_PICKER_INTERVAL) {
159+
super.onClick(dialog, which);
160+
} else {
161+
switch (which) {
162+
case BUTTON_POSITIVE:
163+
final int hours = mTimePicker.getCurrentHour();
164+
int minutes = mTimePicker.getCurrentMinute();
165+
166+
if (mTimePickerInterval > RNConstants.DEFAULT_TIME_PICKER_INTERVAL) {
167+
final int realMinutes = getRealMinutes(minutes);
168+
minutes = realMinutes;
169+
170+
if (pickerIsInTextInputMode() && minutesAreInvalid(realMinutes)) {
171+
minutes = snapMinutesToInterval(realMinutes);
172+
}
173+
}
174+
175+
if (mTimeSetListener != null) {
176+
mTimeSetListener.onTimeSet(mTimePicker, hours, minutes);
177+
}
178+
break;
179+
case BUTTON_NEGATIVE:
180+
cancel();
181+
break;
182+
}
211183
}
184+
}
212185

213-
minutePicker.setDisplayedValues(displayedValues.toArray(new String[0]));
214-
}
186+
@Override
187+
public void updateTime(int hourOfDay, int minuteOfHour) {
188+
mTimePicker.setCurrentMinute(snapMinutesToInterval(minuteOfHour));
189+
}
190+
191+
/**
192+
* Apply visual style in 'spinner' mode
193+
* Adjust minutes to correspond selected interval
194+
*/
195+
@Override
196+
public void onAttachedToWindow() {
197+
super.onAttachedToWindow();
198+
199+
if (mTimePickerInterval > RNConstants.DEFAULT_TIME_PICKER_INTERVAL) {
200+
int timePickerId = mContext.getResources().getIdentifier("timePicker", "id", "android");
201+
202+
mTimePicker = this.findViewById(timePickerId);
203+
int currentMinute = mTimePicker.getCurrentMinute();
204+
205+
if (mDisplay == RNTimePickerDisplay.SPINNER) {
206+
int minutePickerId = mContext.getResources().getIdentifier("minute", "id", "android");
207+
NumberPicker minutePicker = this.findViewById(minutePickerId);
215208

216-
mTimePicker.setCurrentMinute(snapMinutesToInterval(currentMinute));
209+
minutePicker.setMinValue(0);
210+
minutePicker.setMaxValue((60 / mTimePickerInterval) - 1);
211+
212+
List<String> displayedValues = new ArrayList<>();
213+
for (int i = 0; i < 60; i += mTimePickerInterval) {
214+
displayedValues.add(String.format("%02d", i));
215+
}
216+
217+
minutePicker.setDisplayedValues(displayedValues.toArray(new String[0]));
218+
}
219+
220+
mTimePicker.setCurrentMinute(snapMinutesToInterval(currentMinute));
221+
}
217222
}
218-
}
219223
}

0 commit comments

Comments
 (0)