Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.os.Bundle;
import androidx.core.view.ViewCompat;
import androidx.fragment.app.DialogFragment;
import androidx.appcompat.widget.TooltipCompat;
import android.text.TextUtils;
Expand Down Expand Up @@ -112,9 +113,11 @@ public final class MaterialTimePicker extends DialogFragment implements OnDouble
static final String NEGATIVE_BUTTON_TEXT_EXTRA = "TIME_PICKER_NEGATIVE_BUTTON_TEXT";
static final String OVERRIDE_THEME_RES_ID = "TIME_PICKER_OVERRIDE_THEME_RES_ID";

private ViewGroup root;
private MaterialButton modeButton;
private Button okButton;
private Button cancelButton;
private TextView headerTitle;

@InputMode private int inputMode = INPUT_MODE_CLOCK;

Expand Down Expand Up @@ -270,23 +273,16 @@ public final View onCreateView(
@NonNull LayoutInflater layoutInflater,
@Nullable ViewGroup viewGroup,
@Nullable Bundle bundle) {
ViewGroup root =
(ViewGroup) layoutInflater.inflate(R.layout.material_timepicker_dialog, viewGroup);
root = (ViewGroup) layoutInflater.inflate(R.layout.material_timepicker_dialog, viewGroup);
timePickerView = root.findViewById(R.id.material_timepicker_view);
timePickerView.setOnDoubleTapListener(this);
textInputStub = root.findViewById(R.id.material_textinput_timepicker);
modeButton = root.findViewById(R.id.material_timepicker_mode_button);
okButton = root.findViewById(R.id.material_timepicker_ok_button);
cancelButton = root.findViewById(R.id.material_timepicker_cancel_button);
TextView headerTitle = root.findViewById(R.id.header_title);
headerTitle = root.findViewById(R.id.header_title);

if (titleResId != 0) {
headerTitle.setText(titleResId);
} else if (!TextUtils.isEmpty(titleText)) {
headerTitle.setText(titleText);
}

updateInputMode(modeButton);
updateInputMode(inputMode, /* force= */ true);
okButton.setOnClickListener(
v -> {
if (activePresenter instanceof TimePickerTextInputPresenter) {
Expand Down Expand Up @@ -323,10 +319,7 @@ public final View onCreateView(
updateCancelButtonVisibility();

modeButton.setOnClickListener(
v -> {
inputMode = (inputMode == INPUT_MODE_CLOCK) ? INPUT_MODE_KEYBOARD : INPUT_MODE_CLOCK;
updateInputMode(modeButton);
});
v -> updateInputMode(inputMode == INPUT_MODE_CLOCK ? INPUT_MODE_KEYBOARD : INPUT_MODE_CLOCK));

return root;
}
Expand Down Expand Up @@ -385,13 +378,28 @@ public void setCancelable(boolean cancelable) {
@RestrictTo(LIBRARY_GROUP)
@Override
public void onDoubleTap() {
inputMode = INPUT_MODE_KEYBOARD;
updateInputMode(modeButton);
updateInputMode(INPUT_MODE_KEYBOARD);
timePickerTextInputPresenter.resetChecked();
}

private void updateInputMode(MaterialButton modeButton) {
if (modeButton == null || timePickerView == null || textInputStub == null) {
private void updateInputMode(@InputMode int inputMode) {
updateInputMode(inputMode, /* force= */ false);
}

private void updateInputMode(@InputMode int inputMode, boolean force) {
if (!force && this.inputMode == inputMode) {
return;
}

this.inputMode = inputMode;

updateActivePresenter(inputMode);
updateModeButton(inputMode);
updateHeader(inputMode);
}

private void updateActivePresenter(@InputMode int inputMode) {
if (timePickerView == null || textInputStub == null) {
return;
}

Expand All @@ -403,16 +411,67 @@ private void updateInputMode(MaterialButton modeButton) {
initializeOrRetrieveActivePresenterForMode(inputMode, timePickerView, textInputStub);
activePresenter.show();
activePresenter.invalidate();
ModeButtonData modeButtonData = getModeButtonData(inputMode);
modeButton.setIconResource(modeButtonData.iconResId);
modeButton.setContentDescription(
getResources().getString(modeButtonData.contentDescriptionResId));
TooltipCompat.setTooltipText(
modeButton, getResources().getString(modeButtonData.tooltipTextResId));
}

private void updateModeButton(@InputMode int inputMode) {
if (modeButton == null) {
return;
}

@DrawableRes final int iconResId;
@StringRes final int contentDescriptionResId;
@StringRes final int tooltipTextResId;

switch (inputMode) {
case INPUT_MODE_KEYBOARD:
iconResId = clockIcon;
contentDescriptionResId = R.string.material_timepicker_clock_mode_description;
tooltipTextResId = R.string.material_timepicker_clock_mode_tooltip;
break;
case INPUT_MODE_CLOCK:
iconResId = keyboardIcon;
contentDescriptionResId = R.string.material_timepicker_text_input_mode_description;
tooltipTextResId = R.string.material_timepicker_text_input_mode_tooltip;
break;
default:
throw new IllegalArgumentException("Unexpected input mode: " + inputMode);
}

modeButton.setIconResource(iconResId);
modeButton.setContentDescription(getString(contentDescriptionResId));
TooltipCompat.setTooltipText(modeButton, getString(tooltipTextResId));
modeButton.sendAccessibilityEvent(
AccessibilityEventCompat.CONTENT_CHANGE_TYPE_CONTENT_DESCRIPTION);
}

private void updateHeader(int inputMode) {
if (root == null || headerTitle == null) {
return;
}

final CharSequence title;

if (titleResId != 0) {
title = getString(titleResId);
} else if (!TextUtils.isEmpty(titleText)) {
title = titleText;
} else {
switch (inputMode) {
case INPUT_MODE_KEYBOARD:
title = getString(R.string.material_timepicker_enter_time);
break;
case INPUT_MODE_CLOCK:
title = getString(R.string.material_timepicker_select_time);
break;
default:
throw new IllegalArgumentException("Unexpected input mode: " + inputMode);
}
}

headerTitle.setText(title);
ViewCompat.setAccessibilityPaneTitle(root, title);
}

private void updateCancelButtonVisibility() {
if (cancelButton != null) {
cancelButton.setVisibility(isCancelable() ? View.VISIBLE : View.GONE);
Expand Down Expand Up @@ -441,23 +500,6 @@ private TimePickerPresenter initializeOrRetrieveActivePresenterForMode(
return timePickerTextInputPresenter;
}

private ModeButtonData getModeButtonData(@InputMode int mode) {
switch (mode) {
case INPUT_MODE_KEYBOARD:
return new ModeButtonData(
clockIcon,
R.string.material_timepicker_clock_mode_description,
R.string.material_timepicker_clock_mode_tooltip);
case INPUT_MODE_CLOCK:
return new ModeButtonData(
keyboardIcon,
R.string.material_timepicker_text_input_mode_description,
R.string.material_timepicker_text_input_mode_tooltip);
default:
throw new IllegalArgumentException("no button data for mode: " + mode);
}
}

@Nullable
TimePickerClockPresenter getTimePickerClockPresenter() {
return timePickerClockPresenter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:accessibilityPaneTitle="@string/material_timepicker_select_time"
android:paddingBottom="2dp">

<TextView
Expand All @@ -31,7 +30,6 @@
android:layout_marginTop="16dp"
android:layout_marginStart="24dp"
android:importantForAccessibility="yes"
android:text="@string/material_timepicker_select_time"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="material_timepicker_pm" description="Suffix for time in 12-hour standard, after noon. [CHAR_LIMIT=2]">PM</string>
<string name="material_timepicker_am" description="Suffix for time in 12-hour standard, before noon. [CHAR_LIMIT=2]">AM</string>
<string name="material_timepicker_select_time" description="Title for the dialog with a time picker. [CHAR_LIMIT=32]">Select time</string>
<string name="material_timepicker_select_time" description="Title for the dialog with a dial time picker. [CHAR_LIMIT=32]">Select time</string>
<string name="material_timepicker_enter_time" description="Title for the dialog with an input time picker. [CHAR_LIMIT=32]">Enter time</string>
<string name="material_timepicker_minute" description="The label for a text field to select the minute on the hour [CHAR_LIMIT=24]">Minute</string>
<string name="material_timepicker_hour" description="The label for a text field to select the hour on the time [CHAR_LIMIT=24]">Hour</string>
<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>
Expand Down