Show entire bottom sheet with EditText above Keyboard

Show entire bottom sheet with EditText above Keyboard

Salvatrix Ngải Author: Salvatrix Ngải Date: 2022-08-11
Show entire bottom sheet with EditText above Keyboard

    1. FAILURE
    2. implementing a UI where a bottom sheet will appear above the keyboard with an EditText for the user to enter a value. The problem is the View is being partially overlapped by the keyboard, covering up the bottom of the bottom sheet.

    3. Most common Solution
    4. Just reposting @jblejder from this question Keyboard hides BottomSheetDialogFragment since it worked for me, to make it easier for others to find:

      The most convenient way that I found to change this is by creating style:

      <style name="DialogStyle" parent="Theme.Design.Light.BottomSheetDialog">
          <item name="android:windowIsFloating">false</item>
          <item name="android:statusBarColor">@android:color/transparent</item>
          <item name="android:windowSoftInputMode">adjustResize</item>
      </style>
      

      And set this in onCreate method of your BottomSheetDialogFragment:

      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setStyle(DialogFragment.STYLE_NORMAL, R.style.DialogStyle)
      }
      

      This is how it looks on my device:

      enter image description here

      ==== UPDATE ====

      As already mentioned in the Comments a few times, you might also need to set the state of the BottomSheetDialog to STATE_EXPANDED like in Nordknight's answer below

      dialog = new BottomSheetDialog(getContext(), R.style.BottomSheetDialog);  
      dialog.setOnShowListener(new DialogInterface.OnShowListener() {
      @Override
      public void onShow(DialogInterface dialog) {
                  new Handler().postDelayed(new Runnable() {
                      @Override
                      public void run() {
                          BottomSheetDialog d = (BottomSheetDialog) dialog;
                          FrameLayout bottomSheet = d.findViewById(R.id.design_bottom_sheet);
                          BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
                          bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                      }
                  },0);
              }
          });
      

    5. Solution 2
    6. This might be a redundant answer. Although just pointing out the issue. If you're using BottomSheetDialogFragment, the only way is to enable the attribute android:windowIsFloating to true. This will enable the whole window to be on top of whatever is trying to take the space behind it.

      <style name="BottomSheetDialogThemeNoFloating" parent="Theme.Design.Light.BottomSheetDialog">
              <item name="android:windowIsFloating">false</item>
              <item name="android:windowSoftInputMode">adjustResize|stateVisible</item>
      </style>
      

      Then in your onCreate() of your dialog, set this style.

      override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              // set the window no floating style
              setStyle(DialogFragment.STYLE_NORMAL, R.style.AppRoundedBottomSheetDialogThemeNoFloating)
      }
      

      This is handy for those who frequently use bottom sheets and may want to deal with EditText and soft keyboard overlapping each other.

      Note: The class KeyboardUtil by mikepenz has an issue in which on certain phones, the content view with input field is automatically pushed above keyboard despite giving bottom padding to the whole content view supplied.

    7. Solution 3
    8. dialog = new BottomSheetDialog(getContext(), R.style.BottomSheetDialog);  
      dialog.setOnShowListener(new DialogInterface.OnShowListener() {
      @Override
      public void onShow(DialogInterface dialog) {
                  new Handler().postDelayed(new Runnable() {
                      @Override
                      public void run() {
                          BottomSheetDialog d = (BottomSheetDialog) dialog;
                          FrameLayout bottomSheet = d.findViewById(R.id.design_bottom_sheet);
                          BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
                          bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                      }
                  },0);
              }
          });
      

      This code works fine at Fragment's onCreateView method (thanks for ADM)

    9. Solution 4
    10. Some answers seem to do the trick better than others but will need modification when using the new material design components instead of the older support libraries while also using kotlin

      Hope this will help someone.

      BottomSheetDialog(this, R.style.DialogStyle).apply {
          setContentView(layoutInflater.inflate(R.layout.bottom_sheet, null))
          window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
          findViewById<EditText>(R.id.time_et)?.requestFocus()
      
          show()
      }
      

      layout/bottom_sheet.xml

      <?xml version="1.0" encoding="utf-8"?>
      <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:background="#ffffff"
              android:padding="16dp">
      
          <LinearLayout
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:orientation="vertical">
      
      
              <LinearLayout
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:orientation="horizontal">
      
                  <View
                          android:layout_width="0dp"
                          android:layout_height="match_parent"
                          android:layout_weight="1" />
      
                  <LinearLayout
                          android:layout_width="0dp"
                          android:layout_height="wrap_content"
                          android:layout_weight="5"
                          android:orientation="vertical">
      
                      <TextView
                              android:layout_width="wrap_content"
                              android:layout_height="wrap_content"
                              android:text="Time"
                              android:textColor="#000000"
                              android:textSize="24sp"
                              android:textStyle="bold" />
      
                      <LinearLayout
                              android:layout_width="wrap_content"
                              android:layout_height="wrap_content"
                              android:layout_marginTop="8dp"
                              android:orientation="horizontal">
      
                          <EditText
                                  android:id="@+id/time_et"
                                  android:layout_width="wrap_content"
                                  android:layout_height="wrap_content"
                                  android:inputType="numberSigned"
                                  android:minWidth="50dp"
                                  android:text="15" />
      
                          <TextView
                                  android:layout_width="wrap_content"
                                  android:layout_height="wrap_content"
                                  android:layout_marginLeft="8dp"
                                  android:text="min" />
      
                      </LinearLayout>
      
      
                  </LinearLayout>
      
              </LinearLayout>
      
      
              <Button
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:layout_marginTop="16dp"
                      android:background="#000"
                      android:text="Save"
                      android:textColor="#fff" />
      
          </LinearLayout>
      
      </ScrollView>
      

      styes.xml (Split for v-21 for using statusBarColor)

          <style name="DialogStyle" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
              <item name="android:windowIsFloating">false</item>
              <item name="android:statusBarColor">@android:color/transparent</item>
              <item name="android:windowSoftInputMode">adjustResize</item>
          </style>