Skip to content

Commit 0e6c21d

Browse files
zkovarpekingme
andcommitted
[MaterialDatePicker] Ability to Start Picker in MaterialTextInputPicker Mode
Resolves #867 Resolves #865 GIT_ORIGIN_REV_ID=de3f50710c06d17331d366eb9b4d240ec205a1f8 Co-authored-by: pekingme <[email protected]> PiperOrigin-RevId: 289676795
1 parent 9e4ff30 commit 0e6c21d

File tree

5 files changed

+106
-2
lines changed

5 files changed

+106
-2
lines changed

catalog/java/io/material/catalog/datepicker/DatePickerMainDemoFragment.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ public View onCreateDemoView(
9595
final RadioGroup title = root.findViewById(R.id.cat_picker_title_group);
9696
final RadioGroup opening = root.findViewById(R.id.cat_picker_opening_month_group);
9797
final RadioGroup selection = root.findViewById(R.id.cat_picker_selection_group);
98+
final RadioGroup inputMode = root.findViewById(R.id.cat_picker_input_mode_group);
9899

99100
launcher.setOnClickListener(
100101
v -> {
@@ -106,9 +107,10 @@ public View onCreateDemoView(
106107
int titleChoice = title.getCheckedRadioButtonId();
107108
int openingChoice = opening.getCheckedRadioButtonId();
108109
int selectionChoice = selection.getCheckedRadioButtonId();
110+
int inputModeChoices = inputMode.getCheckedRadioButtonId();
109111

110112
MaterialDatePicker.Builder<?> builder =
111-
setupDateSelectorBuilder(selectionModeChoice, selectionChoice);
113+
setupDateSelectorBuilder(selectionModeChoice, selectionChoice, inputModeChoices);
112114
CalendarConstraints.Builder constraintsBuilder =
113115
setupConstraintsBuilder(boundsChoice, openingChoice, validationChoice);
114116

@@ -137,14 +139,19 @@ public View onCreateDemoView(
137139
}
138140

139141
private MaterialDatePicker.Builder<?> setupDateSelectorBuilder(
140-
int selectionModeChoice, int selectionChoice) {
142+
int selectionModeChoice, int selectionChoice, int inputModeChoice) {
141143
if (selectionModeChoice == R.id.cat_picker_date_selector_single) {
142144
MaterialDatePicker.Builder<Long> builder = MaterialDatePicker.Builder.datePicker();
143145
if (selectionChoice == R.id.cat_picker_selection_today) {
144146
builder.setSelection(today);
145147
} else if (selectionChoice == R.id.cat_picker_selection_next_month) {
146148
builder.setSelection(nextMonth);
147149
}
150+
151+
builder.setInputMode(
152+
inputModeChoice == R.id.cat_picker_input_mode_calendar
153+
? MaterialDatePicker.INPUT_MODE_CALENDAR
154+
: MaterialDatePicker.INPUT_MODE_TEXT);
148155
return builder;
149156
} else {
150157
MaterialDatePicker.Builder<Pair<Long, Long>> builder =
@@ -154,6 +161,10 @@ private MaterialDatePicker.Builder<?> setupDateSelectorBuilder(
154161
} else if (selectionChoice == R.id.cat_picker_selection_next_month) {
155162
builder.setSelection(nextMonthPair);
156163
}
164+
builder.setInputMode(
165+
inputModeChoice == R.id.cat_picker_input_mode_text
166+
? MaterialDatePicker.INPUT_MODE_CALENDAR
167+
: MaterialDatePicker.INPUT_MODE_TEXT);
157168
return builder;
158169
}
159170
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
3+
<!--
4+
Copyright 2020 The Android Open Source Project
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
https://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
-->
18+
19+
<LinearLayout
20+
xmlns:android="http://schemas.android.com/apk/res/android"
21+
android:id="@+id/cat_picker_input_mode"
22+
android:layout_width="match_parent"
23+
android:layout_height="wrap_content"
24+
android:padding="@dimen/cat_picker_demo_padding"
25+
android:orientation="vertical">
26+
<TextView
27+
android:layout_width="match_parent"
28+
android:layout_height="wrap_content"
29+
android:text="@string/cat_picker_input_mode"
30+
android:textAppearance="?attr/textAppearanceHeadline5"/>
31+
<RadioGroup
32+
android:id="@+id/cat_picker_input_mode_group"
33+
android:layout_width="match_parent"
34+
android:layout_height="wrap_content"
35+
android:orientation="horizontal">
36+
<RadioButton
37+
android:id="@+id/cat_picker_input_mode_calendar"
38+
android:layout_width="wrap_content"
39+
android:layout_height="wrap_content"
40+
android:checked="true"
41+
android:text="@string/cat_picker_input_mode_calendar"
42+
android:textAppearance="?attr/textAppearanceBody1"/>
43+
<RadioButton
44+
android:id="@+id/cat_picker_input_mode_text"
45+
android:layout_width="wrap_content"
46+
android:layout_height="wrap_content"
47+
android:layout_marginStart="@dimen/cat_picker_demo_padding"
48+
android:layout_marginLeft="@dimen/cat_picker_demo_padding"
49+
android:text="@string/cat_picker_input_mode_text"
50+
android:textAppearance="?attr/textAppearanceBody1"/>
51+
52+
</RadioGroup>
53+
</LinearLayout>

catalog/java/io/material/catalog/datepicker/res/layout/picker_main_demo.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
<include layout="@layout/cat_picker_title"/>
4242
<include layout="@layout/cat_picker_opening_month"/>
4343
<include layout="@layout/cat_picker_selection"/>
44+
<include layout="@layout/cat_picker_input_mode"/>
4445

4546
</LinearLayout>
4647

catalog/java/io/material/catalog/datepicker/res/values/strings.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,11 @@
9191
<!-- Indicates that the picker will open to next month [CHAR LIMIT=25] -->
9292
<string name="cat_picker_opening_month_next">Next Month</string>
9393

94+
<!-- Grouping label for a set of radio buttons that choose the input mode [CHAR LIMIT=50] -->
95+
<string name="cat_picker_input_mode">Input Mode</string>
96+
<!-- Indicates that the picker will start with calendar mode [CHAR LIMIT=25] -->
97+
<string name="cat_picker_input_mode_calendar">Calendar</string>
98+
<!-- Indicates that the picker will start with text input mode [CHAR LIMIT=25] -->
99+
<string name="cat_picker_input_mode_text">Text Input</string>
100+
94101
</resources>

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
import com.google.android.material.R;
2020

21+
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
22+
2123
import android.app.Dialog;
2224
import android.content.Context;
2325
import android.content.DialogInterface;
@@ -29,8 +31,10 @@
2931
import android.graphics.drawable.InsetDrawable;
3032
import android.graphics.drawable.StateListDrawable;
3133
import android.os.Bundle;
34+
import androidx.annotation.IntDef;
3235
import androidx.annotation.NonNull;
3336
import androidx.annotation.Nullable;
37+
import androidx.annotation.RestrictTo;
3438
import androidx.annotation.StringRes;
3539
import androidx.annotation.StyleRes;
3640
import androidx.fragment.app.DialogFragment;
@@ -50,6 +54,8 @@
5054
import com.google.android.material.internal.CheckableImageButton;
5155
import com.google.android.material.resources.MaterialAttributes;
5256
import com.google.android.material.shape.MaterialShapeDrawable;
57+
import java.lang.annotation.Retention;
58+
import java.lang.annotation.RetentionPolicy;
5359
import java.util.LinkedHashSet;
5460

5561
/** A {@link Dialog} with a header, {@link MaterialCalendar}, and set of actions. */
@@ -60,11 +66,24 @@ public final class MaterialDatePicker<S> extends DialogFragment {
6066
private static final String CALENDAR_CONSTRAINTS_KEY = "CALENDAR_CONSTRAINTS_KEY";
6167
private static final String TITLE_TEXT_RES_ID_KEY = "TITLE_TEXT_RES_ID_KEY";
6268
private static final String TITLE_TEXT_KEY = "TITLE_TEXT_KEY";
69+
private static final String INPUT_MODE_KEY = "INPUT_MODE_KEY";
6370

6471
static final Object CONFIRM_BUTTON_TAG = "CONFIRM_BUTTON_TAG";
6572
static final Object CANCEL_BUTTON_TAG = "CANCEL_BUTTON_TAG";
6673
static final Object TOGGLE_BUTTON_TAG = "TOGGLE_BUTTON_TAG";
6774

75+
/** Date picker will start with calendar view. */
76+
public static final int INPUT_MODE_CALENDAR = 0;
77+
78+
/** Date picker will start with input text view. */
79+
public static final int INPUT_MODE_TEXT = 1;
80+
81+
/** @hide */
82+
@RestrictTo(LIBRARY_GROUP)
83+
@IntDef(value = {INPUT_MODE_CALENDAR, INPUT_MODE_TEXT})
84+
@Retention(RetentionPolicy.SOURCE)
85+
public @interface InputMode {}
86+
6887
/** Returns the UTC milliseconds representing the first moment of today in local timezone. */
6988
public static long todayInUtcMilliseconds() {
7089
return UtcDates.getTodayCalendar().getTimeInMillis();
@@ -103,6 +122,7 @@ public String getHeaderText() {
103122
@StringRes private int titleTextResId;
104123
private CharSequence titleText;
105124
private boolean fullscreen;
125+
@InputMode private int inputMode;
106126

107127
private TextView headerSelectionText;
108128
private CheckableImageButton headerToggleButton;
@@ -118,6 +138,7 @@ static <S> MaterialDatePicker<S> newInstance(@NonNull Builder<S> options) {
118138
args.putParcelable(CALENDAR_CONSTRAINTS_KEY, options.calendarConstraints);
119139
args.putInt(TITLE_TEXT_RES_ID_KEY, options.titleTextResId);
120140
args.putCharSequence(TITLE_TEXT_KEY, options.titleText);
141+
args.putInt(INPUT_MODE_KEY, options.inputMode);
121142
materialDatePickerDialogFragment.setArguments(args);
122143
return materialDatePickerDialogFragment;
123144
}
@@ -147,6 +168,7 @@ public final void onCreate(@Nullable Bundle bundle) {
147168
calendarConstraints = activeBundle.getParcelable(CALENDAR_CONSTRAINTS_KEY);
148169
titleTextResId = activeBundle.getInt(TITLE_TEXT_RES_ID_KEY);
149170
titleText = activeBundle.getCharSequence(TITLE_TEXT_KEY);
171+
inputMode = activeBundle.getInt(INPUT_MODE_KEY);
150172
}
151173

152174
private int getThemeResId(Context context) {
@@ -339,6 +361,8 @@ public void onSelectionChanged(S selection) {
339361
private void initHeaderToggle(Context context) {
340362
headerToggleButton.setTag(TOGGLE_BUTTON_TAG);
341363
headerToggleButton.setImageDrawable(createHeaderToggleDrawable(context));
364+
headerToggleButton.setChecked(inputMode != INPUT_MODE_CALENDAR);
365+
342366
// By default, CheckableImageButton adds a delegate that reads checked state.
343367
// This information is not useful; we remove the delegate and use custom content descriptions.
344368
ViewCompat.setAccessibilityDelegate(headerToggleButton, null);
@@ -504,6 +528,7 @@ public static final class Builder<S> {
504528
int titleTextResId = 0;
505529
CharSequence titleText = null;
506530
@Nullable S selection = null;
531+
@InputMode int inputMode = INPUT_MODE_CALENDAR;
507532

508533
private Builder(DateSelector<S> dateSelector) {
509534
this.dateSelector = dateSelector;
@@ -575,6 +600,13 @@ public Builder<S> setTitleText(@Nullable CharSequence charSequence) {
575600
return this;
576601
}
577602

603+
/** Sets the input mode to start with. */
604+
@NonNull
605+
public Builder<S> setInputMode(@InputMode int inputMode) {
606+
this.inputMode = inputMode;
607+
return this;
608+
}
609+
578610
/** Creates a {@link MaterialDatePicker} with the provided options. */
579611
@NonNull
580612
public MaterialDatePicker<S> build() {

0 commit comments

Comments
 (0)