Skip to content

Commit f843ab0

Browse files
Material Design Teampaulfthomas
authored andcommitted
[Date Picker] Avoid re-creating text input picker fragment on configuration changes
Addresses an issue where the input text view was losing entered text and cursor position during configuration changes. PiperOrigin-RevId: 769580976
1 parent 7df9b07 commit f843ab0

File tree

5 files changed

+36
-18
lines changed

5 files changed

+36
-18
lines changed

lib/java/com/google/android/material/datepicker/MaterialDatePicker.java

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import android.graphics.drawable.StateListDrawable;
3434
import android.os.Bundle;
3535
import androidx.fragment.app.DialogFragment;
36-
import androidx.fragment.app.FragmentTransaction;
36+
import androidx.fragment.app.Fragment;
3737
import androidx.appcompat.content.res.AppCompatResources;
3838
import android.text.TextUtils;
3939
import android.view.LayoutInflater;
@@ -96,6 +96,8 @@ public class MaterialDatePicker<S> extends DialogFragment {
9696
private static final String NEGATIVE_BUTTON_CONTENT_DESCRIPTION_KEY =
9797
"NEGATIVE_BUTTON_CONTENT_DESCRIPTION_KEY";
9898
private static final String INPUT_MODE_KEY = "INPUT_MODE_KEY";
99+
private static final String CALENDAR_FRAGMENT_TAG = "CALENDAR_FRAGMENT_TAG";
100+
private static final String TEXT_INPUT_FRAGMENT_TAG = "TEXT_INPUT_FRAGMENT_TAG";
99101

100102
static final Object CONFIRM_BUTTON_TAG = "CONFIRM_BUTTON_TAG";
101103
static final Object CANCEL_BUTTON_TAG = "CANCEL_BUTTON_TAG";
@@ -502,22 +504,27 @@ private String getHeaderContentDescription() {
502504

503505
private void startPickerFragment() {
504506
int themeResId = getThemeResId(requireContext());
505-
calendar =
506-
MaterialCalendar.newInstance(
507-
getDateSelector(), themeResId, calendarConstraints, dayViewDecorator);
508-
509-
pickerFragment =
510-
inputMode == INPUT_MODE_TEXT
511-
? MaterialTextInputPicker.newInstance(
512-
getDateSelector(), themeResId, calendarConstraints)
513-
: calendar;
514-
updateTitle();
515-
updateHeader(getHeaderText());
516-
517-
FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
518-
fragmentTransaction.replace(R.id.mtrl_calendar_frame, pickerFragment);
519-
fragmentTransaction.commitNow();
507+
String currentTag =
508+
inputMode == INPUT_MODE_TEXT ? TEXT_INPUT_FRAGMENT_TAG : CALENDAR_FRAGMENT_TAG;
509+
510+
Fragment foundFragment = getChildFragmentManager().findFragmentByTag(currentTag);
511+
@SuppressWarnings("unchecked")
512+
PickerFragment<S> fragment =
513+
foundFragment instanceof PickerFragment ? (PickerFragment<S>) foundFragment : null;
514+
515+
if (fragment == null) {
516+
if (inputMode == INPUT_MODE_TEXT) {
517+
fragment =
518+
MaterialTextInputPicker.newInstance(getDateSelector(), themeResId, calendarConstraints);
519+
} else {
520+
calendar =
521+
MaterialCalendar.newInstance(
522+
getDateSelector(), themeResId, calendarConstraints, dayViewDecorator);
523+
fragment = calendar;
524+
}
525+
}
520526

527+
pickerFragment = fragment;
521528
pickerFragment.addOnSelectionChangedListener(
522529
new OnSelectionChangedListener<S>() {
523530
@Override
@@ -531,6 +538,14 @@ public void onIncompleteSelectionChanged() {
531538
confirmButton.setEnabled(false);
532539
}
533540
});
541+
542+
updateTitle();
543+
updateHeader(getHeaderText());
544+
545+
getChildFragmentManager()
546+
.beginTransaction()
547+
.replace(R.id.mtrl_calendar_frame, pickerFragment, currentTag)
548+
.commitNow();
534549
}
535550

536551
private void initHeaderToggle(Context context) {

lib/java/com/google/android/material/datepicker/RangeDateSelector.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ public View onCreateTextInputView(
238238
// Move the cursor to the end of the text field
239239
CharSequence text = startEditText.getText();
240240
if (text != null) {
241-
startEditText.post(() -> startEditText.setSelection(text.length()));
241+
startEditText.setSelection(text.length());
242242
}
243243
}
244244
if (selectedEndItem != null) {

lib/java/com/google/android/material/datepicker/SingleDateSelector.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ public View onCreateTextInputView(
138138
// Move the cursor to the end of the text field
139139
CharSequence text = dateEditText.getText();
140140
if (text != null) {
141-
dateEditText.post(() -> dateEditText.setSelection(text.length()));
141+
dateEditText.setSelection(text.length());
142142
}
143143
}
144144

lib/java/com/google/android/material/datepicker/res/layout/mtrl_picker_text_input_date.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
android:layout_gravity="center_horizontal">
3333

3434
<com.google.android.material.textfield.TextInputEditText
35+
android:id="@+id/mtrl_picker_edit_text_date"
3536
android:layout_width="match_parent"
3637
android:layout_height="wrap_content"
3738
android:hint="@string/mtrl_picker_text_input_date_hint"

lib/java/com/google/android/material/datepicker/res/layout/mtrl_picker_text_input_date_range.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
android:layout_gravity="center_horizontal">
3636

3737
<com.google.android.material.textfield.TextInputEditText
38+
android:id="@+id/mtrl_picker_edit_text_range_start"
3839
android:layout_width="match_parent"
3940
android:layout_height="wrap_content"
4041
android:hint="@string/mtrl_picker_text_input_date_range_start_hint"
@@ -55,6 +56,7 @@
5556
android:layout_gravity="center_horizontal">
5657

5758
<com.google.android.material.textfield.TextInputEditText
59+
android:id="@+id/mtrl_picker_edit_text_range_end"
5860
android:layout_width="match_parent"
5961
android:layout_height="wrap_content"
6062
android:hint="@string/mtrl_picker_text_input_date_range_end_hint"

0 commit comments

Comments
 (0)