2929import android .content .res .ColorStateList ;
3030import android .content .res .TypedArray ;
3131import android .os .Bundle ;
32+ import androidx .core .view .ViewCompat ;
3233import androidx .fragment .app .DialogFragment ;
3334import androidx .appcompat .widget .TooltipCompat ;
3435import 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 ;
0 commit comments