Skip to content

Commit 770e519

Browse files
committed
[TimePicker] Fix default title for text input mode
1 parent c2051db commit 770e519

File tree

3 files changed

+85
-44
lines changed

3 files changed

+85
-44
lines changed

lib/java/com/google/android/material/timepicker/MaterialTimePicker.java

Lines changed: 83 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import android.content.res.ColorStateList;
3030
import android.content.res.TypedArray;
3131
import android.os.Bundle;
32+
import androidx.core.view.ViewCompat;
3233
import androidx.fragment.app.DialogFragment;
3334
import androidx.appcompat.widget.TooltipCompat;
3435
import android.text.TextUtils;
@@ -112,9 +113,11 @@ public final class MaterialTimePicker extends DialogFragment implements OnDouble
112113
static final String NEGATIVE_BUTTON_TEXT_EXTRA = "TIME_PICKER_NEGATIVE_BUTTON_TEXT";
113114
static final String OVERRIDE_THEME_RES_ID = "TIME_PICKER_OVERRIDE_THEME_RES_ID";
114115

116+
private ViewGroup root;
115117
private MaterialButton modeButton;
116118
private Button okButton;
117119
private Button cancelButton;
120+
private TextView headerTitle;
118121

119122
@InputMode private int inputMode = INPUT_MODE_CLOCK;
120123

@@ -270,23 +273,16 @@ public final View onCreateView(
270273
@NonNull LayoutInflater layoutInflater,
271274
@Nullable ViewGroup viewGroup,
272275
@Nullable Bundle bundle) {
273-
ViewGroup root =
274-
(ViewGroup) layoutInflater.inflate(R.layout.material_timepicker_dialog, viewGroup);
276+
root = (ViewGroup) layoutInflater.inflate(R.layout.material_timepicker_dialog, viewGroup);
275277
timePickerView = root.findViewById(R.id.material_timepicker_view);
276278
timePickerView.setOnDoubleTapListener(this);
277279
textInputStub = root.findViewById(R.id.material_textinput_timepicker);
278280
modeButton = root.findViewById(R.id.material_timepicker_mode_button);
279281
okButton = root.findViewById(R.id.material_timepicker_ok_button);
280282
cancelButton = root.findViewById(R.id.material_timepicker_cancel_button);
281-
TextView headerTitle = root.findViewById(R.id.header_title);
283+
headerTitle = root.findViewById(R.id.header_title);
282284

283-
if (titleResId != 0) {
284-
headerTitle.setText(titleResId);
285-
} else if (!TextUtils.isEmpty(titleText)) {
286-
headerTitle.setText(titleText);
287-
}
288-
289-
updateInputMode(modeButton);
285+
updateInputMode(inputMode, /* force= */ true);
290286
okButton.setOnClickListener(
291287
v -> {
292288
if (activePresenter instanceof TimePickerTextInputPresenter) {
@@ -323,10 +319,7 @@ public final View onCreateView(
323319
updateCancelButtonVisibility();
324320

325321
modeButton.setOnClickListener(
326-
v -> {
327-
inputMode = (inputMode == INPUT_MODE_CLOCK) ? INPUT_MODE_KEYBOARD : INPUT_MODE_CLOCK;
328-
updateInputMode(modeButton);
329-
});
322+
v -> updateInputMode(inputMode == INPUT_MODE_CLOCK ? INPUT_MODE_KEYBOARD : INPUT_MODE_CLOCK));
330323

331324
return root;
332325
}
@@ -385,13 +378,28 @@ public void setCancelable(boolean cancelable) {
385378
@RestrictTo(LIBRARY_GROUP)
386379
@Override
387380
public void onDoubleTap() {
388-
inputMode = INPUT_MODE_KEYBOARD;
389-
updateInputMode(modeButton);
381+
updateInputMode(INPUT_MODE_KEYBOARD);
390382
timePickerTextInputPresenter.resetChecked();
391383
}
392384

393-
private void updateInputMode(MaterialButton modeButton) {
394-
if (modeButton == null || timePickerView == null || textInputStub == null) {
385+
private void updateInputMode(@InputMode int inputMode) {
386+
updateInputMode(inputMode, /* force= */ false);
387+
}
388+
389+
private void updateInputMode(@InputMode int inputMode, boolean force) {
390+
if (!force && this.inputMode == inputMode) {
391+
return;
392+
}
393+
394+
this.inputMode = inputMode;
395+
396+
updateActivePresenter(inputMode);
397+
updateModeButton(inputMode);
398+
updateHeader(inputMode);
399+
}
400+
401+
private void updateActivePresenter(@InputMode int inputMode) {
402+
if (timePickerView == null || textInputStub == null) {
395403
return;
396404
}
397405

@@ -403,16 +411,67 @@ private void updateInputMode(MaterialButton modeButton) {
403411
initializeOrRetrieveActivePresenterForMode(inputMode, timePickerView, textInputStub);
404412
activePresenter.show();
405413
activePresenter.invalidate();
406-
ModeButtonData modeButtonData = getModeButtonData(inputMode);
407-
modeButton.setIconResource(modeButtonData.iconResId);
408-
modeButton.setContentDescription(
409-
getResources().getString(modeButtonData.contentDescriptionResId));
410-
TooltipCompat.setTooltipText(
411-
modeButton, getResources().getString(modeButtonData.tooltipTextResId));
414+
}
415+
416+
private void updateModeButton(@InputMode int inputMode) {
417+
if (modeButton == null) {
418+
return;
419+
}
420+
421+
@DrawableRes final int iconResId;
422+
@StringRes final int contentDescriptionResId;
423+
@StringRes final int tooltipTextResId;
424+
425+
switch (inputMode) {
426+
case INPUT_MODE_KEYBOARD:
427+
iconResId = clockIcon;
428+
contentDescriptionResId = R.string.material_timepicker_clock_mode_description;
429+
tooltipTextResId = R.string.material_timepicker_clock_mode_tooltip;
430+
break;
431+
case INPUT_MODE_CLOCK:
432+
iconResId = keyboardIcon;
433+
contentDescriptionResId = R.string.material_timepicker_text_input_mode_description;
434+
tooltipTextResId = R.string.material_timepicker_text_input_mode_tooltip;
435+
break;
436+
default:
437+
throw new IllegalArgumentException("Unexpected input mode: " + inputMode);
438+
}
439+
440+
modeButton.setIconResource(iconResId);
441+
modeButton.setContentDescription(getString(contentDescriptionResId));
442+
TooltipCompat.setTooltipText(modeButton, getString(tooltipTextResId));
412443
modeButton.sendAccessibilityEvent(
413444
AccessibilityEventCompat.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION);
414445
}
415446

447+
private void updateHeader(int inputMode) {
448+
if (root == null || headerTitle == null) {
449+
return;
450+
}
451+
452+
final CharSequence title;
453+
454+
if (titleResId != 0) {
455+
title = getString(titleResId);
456+
} else if (!TextUtils.isEmpty(titleText)) {
457+
title = titleText;
458+
} else {
459+
switch (inputMode) {
460+
case INPUT_MODE_KEYBOARD:
461+
title = getString(R.string.material_timepicker_enter_time);
462+
break;
463+
case INPUT_MODE_CLOCK:
464+
title = getString(R.string.material_timepicker_select_time);
465+
break;
466+
default:
467+
throw new IllegalArgumentException("Unexpected input mode: " + inputMode);
468+
}
469+
}
470+
471+
headerTitle.setText(title);
472+
ViewCompat.setAccessibilityPaneTitle(root, title);
473+
}
474+
416475
private void updateCancelButtonVisibility() {
417476
if (cancelButton != null) {
418477
cancelButton.setVisibility(isCancelable() ? View.VISIBLE : View.GONE);
@@ -441,23 +500,6 @@ private TimePickerPresenter initializeOrRetrieveActivePresenterForMode(
441500
return timePickerTextInputPresenter;
442501
}
443502

444-
private ModeButtonData getModeButtonData(@InputMode int mode) {
445-
switch (mode) {
446-
case INPUT_MODE_KEYBOARD:
447-
return new ModeButtonData(
448-
clockIcon,
449-
R.string.material_timepicker_clock_mode_description,
450-
R.string.material_timepicker_clock_mode_tooltip);
451-
case INPUT_MODE_CLOCK:
452-
return new ModeButtonData(
453-
keyboardIcon,
454-
R.string.material_timepicker_text_input_mode_description,
455-
R.string.material_timepicker_text_input_mode_tooltip);
456-
default:
457-
throw new IllegalArgumentException("no button data for mode: " + mode);
458-
}
459-
}
460-
461503
@Nullable
462504
TimePickerClockPresenter getTimePickerClockPresenter() {
463505
return timePickerClockPresenter;

lib/java/com/google/android/material/timepicker/res/layout/material_timepicker_dialog.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
xmlns:app="http://schemas.android.com/apk/res-auto"
2121
android:layout_width="wrap_content"
2222
android:layout_height="wrap_content"
23-
android:accessibilityPaneTitle="@string/material_timepicker_select_time"
2423
android:paddingBottom="2dp">
2524

2625
<TextView
@@ -31,7 +30,6 @@
3130
android:layout_marginTop="16dp"
3231
android:layout_marginStart="24dp"
3332
android:importantForAccessibility="yes"
34-
android:text="@string/material_timepicker_select_time"
3533
app:layout_constraintStart_toStartOf="parent"
3634
app:layout_constraintTop_toTopOf="parent" />
3735

lib/java/com/google/android/material/timepicker/res/values/strings.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
1919
<string name="material_timepicker_pm" description="Suffix for time in 12-hour standard, after noon. [CHAR_LIMIT=2]">PM</string>
2020
<string name="material_timepicker_am" description="Suffix for time in 12-hour standard, before noon. [CHAR_LIMIT=2]">AM</string>
21-
<string name="material_timepicker_select_time" description="Title for the dialog with a time picker. [CHAR_LIMIT=32]">Select time</string>
21+
<string name="material_timepicker_select_time" description="Title for the dialog with a dial time picker. [CHAR_LIMIT=32]">Select time</string>
22+
<string name="material_timepicker_enter_time" description="Title for the dialog with an input time picker. [CHAR_LIMIT=32]">Enter time</string>
2223
<string name="material_timepicker_minute" description="The label for a text field to select the minute on the hour [CHAR_LIMIT=24]">Minute</string>
2324
<string name="material_timepicker_hour" description="The label for a text field to select the hour on the time [CHAR_LIMIT=24]">Hour</string>
2425
<string name="material_timepicker_minute_error" description="The label for a text field to show an error on the selection of the minute [CHAR_LIMIT=24]">Minute must be 0–59</string>

0 commit comments

Comments
 (0)