diff --git a/lib/java/com/google/android/material/datepicker/DateSelector.java b/lib/java/com/google/android/material/datepicker/DateSelector.java index 5f473b1fae4..649211130b5 100644 --- a/lib/java/com/google/android/material/datepicker/DateSelector.java +++ b/lib/java/com/google/android/material/datepicker/DateSelector.java @@ -146,6 +146,12 @@ static void showKeyboardWithAutoHideBehavior(@NonNull EditText... editTexts) { editText.setOnFocusChangeListener(listener); } - ViewUtils.requestFocusAndShowKeyboard(editTexts[0]); + // TODO(b/246354286): Investigate issue with keyboard not showing on Android 12+ + View viewToFocus = editTexts[0]; + viewToFocus.postDelayed( + () -> + ViewUtils.requestFocusAndShowKeyboard( + viewToFocus, /* useWindowInsetsController= */ false), + 100); } } diff --git a/lib/java/com/google/android/material/internal/ViewUtils.java b/lib/java/com/google/android/material/internal/ViewUtils.java index cc115268411..70bc3db6555 100644 --- a/lib/java/com/google/android/material/internal/ViewUtils.java +++ b/lib/java/com/google/android/material/internal/ViewUtils.java @@ -80,6 +80,16 @@ public static void showKeyboard(@NonNull View view, boolean useWindowInsetsContr getInputMethodManager(view).showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); } + public static void requestFocusAndShowKeyboard(@NonNull final View view) { + requestFocusAndShowKeyboard(view, /* useWindowInsetsController= */ true); + } + + public static void requestFocusAndShowKeyboard( + @NonNull final View view, boolean useWindowInsetsController) { + view.requestFocus(); + view.post(() -> showKeyboard(view, useWindowInsetsController)); + } + public static void hideKeyboard(@NonNull View view) { hideKeyboard(view, /* useWindowInsetsController= */ true); } @@ -161,20 +171,6 @@ public static float dpToPx(@NonNull Context context, @Dimension(unit = Dimension return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()); } - public static void requestFocusAndShowKeyboard(@NonNull final View view) { - view.requestFocus(); - view.post( - new Runnable() { - @Override - public void run() { - InputMethodManager inputMethodManager = - (InputMethodManager) - view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - inputMethodManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); - } - }); - } - /** * Wrapper around {@link androidx.core.view.OnApplyWindowInsetsListener} which also passes the * initial padding set on the view. Used with {@link #doOnApplyWindowInsets(View, diff --git a/lib/java/com/google/android/material/timepicker/ChipTextInputComboView.java b/lib/java/com/google/android/material/timepicker/ChipTextInputComboView.java index b3add4ae373..883cf3e4ead 100644 --- a/lib/java/com/google/android/material/timepicker/ChipTextInputComboView.java +++ b/lib/java/com/google/android/material/timepicker/ChipTextInputComboView.java @@ -108,7 +108,7 @@ public void setChecked(boolean checked) { // Instead, the text in chip should be hidden. chip.setVisibility(checked ? GONE : VISIBLE); if (isChecked()) { - ViewUtils.requestFocusAndShowKeyboard(editText); + ViewUtils.requestFocusAndShowKeyboard(editText, /* useWindowInsetsController= */ false); } } diff --git a/lib/javatests/com/google/android/material/datepicker/RangeDateSelectorTest.java b/lib/javatests/com/google/android/material/datepicker/RangeDateSelectorTest.java index dc3d7fa1fec..a93f73490fe 100644 --- a/lib/javatests/com/google/android/material/datepicker/RangeDateSelectorTest.java +++ b/lib/javatests/com/google/android/material/datepicker/RangeDateSelectorTest.java @@ -17,6 +17,7 @@ import com.google.android.material.test.R; +import static androidx.core.content.ContextCompat.getSystemService; import static com.google.common.truth.Truth.assertThat; import android.content.Context; @@ -25,6 +26,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; import android.widget.GridView; import android.widget.TextView.BufferType; import androidx.core.util.Pair; @@ -39,7 +41,9 @@ import org.junit.runner.RunWith; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; +import org.robolectric.Shadows; import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowInputMethodManager; import org.robolectric.shadows.ShadowLooper; @RunWith(RobolectricTestRunner.class) @@ -377,6 +381,20 @@ public void getSelectedRanges_partialRange() { assertThat(rangeDateSelector.getSelectedRanges()).containsExactly(selection); } + @Test + public void focusAndShowKeyboardAtStartup() { + InputMethodManager inputMethodManager = getSystemService(activity, InputMethodManager.class); + ShadowInputMethodManager shadowIMM = Shadows.shadowOf(inputMethodManager); + View root = getRootView(); + ((ViewGroup) activity.findViewById(android.R.id.content)).addView(root); + TextInputLayout startTextInput = root.findViewById(R.id.mtrl_picker_text_input_range_start); + + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); + + assertThat(startTextInput.getEditText().isFocused()).isTrue(); + assertThat(shadowIMM.isSoftInputVisible()).isTrue(); + } + private View getRootView() { return rangeDateSelector.onCreateTextInputView( LayoutInflater.from(context), diff --git a/lib/javatests/com/google/android/material/datepicker/SingleDateSelectorTest.java b/lib/javatests/com/google/android/material/datepicker/SingleDateSelectorTest.java index 935cd7b0092..a720b94357c 100644 --- a/lib/javatests/com/google/android/material/datepicker/SingleDateSelectorTest.java +++ b/lib/javatests/com/google/android/material/datepicker/SingleDateSelectorTest.java @@ -17,6 +17,7 @@ import com.google.android.material.test.R; +import static androidx.core.content.ContextCompat.getSystemService; import static com.google.common.truth.Truth.assertThat; import android.content.Context; @@ -25,6 +26,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; import android.widget.GridView; import androidx.annotation.NonNull; import androidx.test.core.app.ApplicationProvider; @@ -37,6 +39,8 @@ import org.junit.runner.RunWith; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; +import org.robolectric.Shadows; +import org.robolectric.shadows.ShadowInputMethodManager; import org.robolectric.shadows.ShadowLooper; @RunWith(RobolectricTestRunner.class) @@ -186,6 +190,20 @@ public void textFieldPlaceholder_usesCustomFormat() { assertThat(textInputLayout.getPlaceholderText().toString()).isEqualTo("kk:mm:ss mm/dd/yyyy"); } + @Test + public void focusAndShowKeyboardAtStartup() { + InputMethodManager inputMethodManager = getSystemService(activity, InputMethodManager.class); + ShadowInputMethodManager shadowIMM = Shadows.shadowOf(inputMethodManager); + View root = getRootView(); + ((ViewGroup) activity.findViewById(android.R.id.content)).addView(root); + TextInputLayout textInputLayout = root.findViewById(R.id.mtrl_picker_text_input_date); + + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); + + assertThat(textInputLayout.getEditText().isFocused()).isTrue(); + assertThat(shadowIMM.isSoftInputVisible()).isTrue(); + } + private View getRootView() { return singleDateSelector.onCreateTextInputView( LayoutInflater.from(context),