Keyboard hides BottomSheetDialogFragment

17,651

Solution 1

I found the solution for 27 api. So the reason why keyboard hides view even with SOFT_INPUT_ADJUST_RESIZE is that the windowIsFloating is set for Dialogs.

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

Solution 2

I tried all of answers in this topic but nothing helped. I looked through many sites and found only one solution that working for me.

 override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    val dialog = super.onCreateDialog(savedInstanceState)

    dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
    dialog.setOnShowListener {
        Handler().post {
            val bottomSheet = (dialog as? BottomSheetDialog)?.findViewById<View>(R.id.design_bottom_sheet) as? FrameLayout
            bottomSheet?.let {
                BottomSheetBehavior.from(it).state = BottomSheetBehavior.STATE_EXPANDED
            }
        }
    }

    return dialog
}

Original solution

Solution 3

You can use the next class:

import android.graphics.Rect; 
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.BottomSheetDialog;
import android.support.design.widget.BottomSheetDialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;

public class TestBottomSheetDialog extends BottomSheetDialogFragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View fragmentView = LayoutInflater.from(getContext()).inflate(R.layout.fragment_bottom_sheet, container, false);
        if (getDialog().getWindow() != null) {
           getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        }
        if (getActivity() != null) {
            View decorView = getActivity().getWindow().getDecorView();
            decorView.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
                Rect displayFrame = new Rect();
                decorView.getWindowVisibleDisplayFrame(displayFrame);
                int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
                int heightDifference = height - displayFrame.bottom;
                if (heightDifference != 0) {
                    if (fragmentView.getPaddingBottom() != heightDifference) {
                        fragmentView.setPadding(0, 0, 0, heightDifference);
                    }
                } else {
                    if (fragmentView.getPaddingBottom() != 0) {
                        fragmentView.setPadding(0, 0, 0, 0);
                    }
                }
            });
        }
        getDialog().setOnShowListener(dialog -> {
            BottomSheetDialog d = (BottomSheetDialog) dialog;
            View bottomSheetInternal = d.findViewById(android.support.design.R.id.design_bottom_sheet);
            if (bottomSheetInternal == null) return;
             BottomSheetBehavior.from(bottomSheetInternal).setState(BottomSheetBehavior.STATE_EXPANDED);
        });
        return fragmentView;
    }
}
Share:
17,651
alvarlagerlof
Author by

alvarlagerlof

Hey there!

Updated on June 04, 2022

Comments

  • alvarlagerlof
    alvarlagerlof almost 2 years

    There are more fields below the keyboard. This happened when i updated the support library. I know it's Kotlin but it looks almost the same as java. How do I fix this issue?

    This is what it looks like:

    enter image description here

    My code:

    class ProjectsEditBottomSheetFragment(val privateID: String,
                                      val publicID: String) : BottomSheetDialogFragment() {
    
    
    
    private val mBottomSheetBehaviorCallback = object : BottomSheetBehavior.BottomSheetCallback() {
        override fun onStateChanged(bottomSheet: View, newState: Int) {
            if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                dismiss()
            }
    
        }
    
    
        override fun onSlide(bottomSheet: View, slideOffset: Float) {
            if (slideOffset < -0.15f) {
                dismiss()
            }
        }
    }
    
    
    override fun setupDialog(dialog: Dialog, style: Int) {
        super.setupDialog(dialog, style)
        val view = View.inflate(context, R.layout.projects_edit_sheet, null)
        dialog.setContentView(view)
    
        dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
    
    
        val params = (view.parent as View).layoutParams as CoordinatorLayout.LayoutParams
        val behavior = params.behavior
    
        if (behavior != null && behavior is BottomSheetBehavior<*>) {
            behavior.setBottomSheetCallback(mBottomSheetBehaviorCallback)
        }
    
    
        // Get and set values
        val realm = Realm.getDefaultInstance()
        val realmObject = realm.where(ProjectsRealmObject::class.java)
                .equalTo("privateID", privateID)
                .findFirst()
    
    
    
    
        realm.beginTransaction()
        view.title_input.text = SpannableStringBuilder(realmObject.title)
        view.description_input.text = SpannableStringBuilder(realmObject.description)
        view.public_checkbox.isChecked = realmObject.isPublic
        realm.commitTransaction()
    
    
        // Keyboard
        view.title_input.onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
            if (hasFocus) {
                (context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).showSoftInput(view.title_input, InputMethodManager.SHOW_FORCED)
            } else {
                (context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(view.title_input.windowToken, 0)
            }
        }
    
        view.description_input.onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
            if (hasFocus) {
                (context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).showSoftInput(view.description_input, InputMethodManager.SHOW_FORCED)
            } else {
                (context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager).hideSoftInputFromWindow(view.description_input.windowToken, 0)
            }
        }
    
    
        // Click listners
        view.public_layout.setOnClickListener { view.public_checkbox.toggle() }
    
        view.cancel.setOnClickListener {
            view?.hideKeyboard()
            dismiss()
        }
    
        view.save.setOnClickListener {
            view?.hideKeyboard()
            // Save to realm
            realm.beginTransaction()
            realmObject.title = if (view.title_input.text.toString() == "") getString(R.string.unnamed) else view.title_input.text.toString()
            realmObject.description = view.description_input.text.toString()
            realmObject.isPublic = view.public_checkbox.isChecked
            realmObject.synced = false
            realmObject.updatedRealm = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()).toString() + ""
            realm.commitTransaction()
    
            ProjectsSync(context)
    
            toast("Sparat")
    
            dismiss()
        }
    
      }
    }
    

    xml:

    <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="@color/white"
    app:layout_collapseMode="none"
    app:behavior_hideable="false"
    app:behavior_peekHeight="100dp"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
    style="@style/Widget.Design.BottomSheet.Modal">
    
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:id="@+id/content">
    
            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingRight="16dp"
                android:paddingLeft="16dp"
                android:layout_marginTop="16dp"
                android:layout_marginBottom="8dp">
    
                <android.support.design.widget.TextInputEditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/edit_info_placeholder_title"
                    android:id="@+id/title_input"/>
    
            </android.support.design.widget.TextInputLayout>
    
            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingRight="16dp"
                android:paddingLeft="16dp">
    
                <android.support.design.widget.TextInputEditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/edit_info_placeholder_description"
                    android:id="@+id/description_input"/>
    
            </android.support.design.widget.TextInputLayout>
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:clickable="true"
                android:background="@drawable/click"
                android:paddingTop="8dp"
                android:paddingBottom="8dp"
                android:id="@+id/public_layout">
    
                <android.support.v7.widget.AppCompatCheckBox
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="12dp"
                    android:id="@+id/public_checkbox"
                    android:layout_marginRight="8dp"/>
    
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/edit_info_placeholder_is_public"
                    android:layout_gravity="center_vertical"
                    style="@style/textMedium"/>
    
            </LinearLayout>
    
    
            <!-- Buttons -->
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:gravity="right"
                android:paddingBottom="8dp">
    
                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/edit_info_button_cancel"
                    android:id="@+id/cancel"
                    style="@style/Widget.AppCompat.Button.Borderless.Colored"/>
    
                <Button
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/edit_info_button_save"
                    android:id="@+id/save"
                    style="@style/Widget.AppCompat.Button.Borderless.Colored"/>
    
            </LinearLayout>
    
        </LinearLayout>
    
    
    </FrameLayout>