1

I'm having trouble with a BottomSheetDialogFragment I implemented some days back in a project I'm in.
What happens is that I have a BottomSheet which contains a SearchView and a Recyclerview. The dialog fragment shows correctly and stuff, all good there.
The problem starts when I use the SearchView to filter the Recyclerview's results since when there's 5 or less results, the keyboard is overlapping the now small Recyclerview.
I want to know if it's possible to keep the BottomSheet height as match_parent or something to fill the window or keep the Recyclerview big enough to avoid the keyboard "messing up" with the results. I use the following method to make the fragment expanded when it opens:

private fun expandBottomSheet() {
    view?.viewTreeObserver?.addOnGlobalLayoutListener {
        val dialog = dialog as BottomSheetDialog

        val bottomSheet = dialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)

        val behavior = BottomSheetBehavior.from<View>(bottomSheet)

        behavior.state = BottomSheetBehavior.STATE_EXPANDED
    }

}

And my XML for the sheet is this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:layout_behavior="@string/bottom_sheet_behavior">

    <View
        android:layout_width="52dp"
        android:layout_height="7dp"
        android:layout_gravity="center"
        android:layout_marginTop="@dimen/size_small_4"
        android:layout_marginBottom="@dimen/size_small_4"
        android:background="@drawable/border_top_swipe_indicator" />

    <androidx.appcompat.widget.SearchView
        android:id="@+id/searchView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:iconifiedByDefault="false"
        app:queryHint="@string/text_type_your_query" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/border_top_white"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        tools:listitem="@layout/list_item" />

</LinearLayout>

Thanks in advance for the help!

Edit:
The bottom sheet containing the Recyclerview and stuff is a child fragment (a fragment instantiated from another fragment.)

pamobo0609
  • 812
  • 10
  • 21

4 Answers4

1

For anyone who is searching for this question, if you want to force your BottomSheetDialogFragment have full screen height, just wrap your bottom sheet content layout inside of this custom FrameLayout:

public class MatchParentFrameLayout extends FrameLayout {
    public MatchParentFrameLayout(@NonNull Context context) {
        super(context);
    }

    public MatchParentFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MatchParentFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public MatchParentFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.EXACTLY);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}
ssynhtn
  • 1,307
  • 12
  • 18
0

In the manifest.xml file you have your activities declared there for your application. Inside of the <activity> block where this bottom sheet is hosted you can declare a window soft input mode so that the keyboard does not overlap the view - instead it pushes it up.

<activity
   ...
   android:windowSoftInputMode="adjustResize|stateVisible"> ... </activity>

stateVisible: "The soft keyboard is visible when that's normally appropriate (when the user is navigating forward to the activity's main window)."

adjustResize: "The activity's main window is always resized to make room for the soft keyboard on screen."

Docs

That should work for you. It could be possible, depending on your views, for that to result in a poor UI and UX. If that is true, you could set a focus listener on the search view and, when it gains focus, programmatically set the state of the bottom sheet to expanded. See the answerhere.

Nathan K
  • 199
  • 7
0

Even though I'm not satisfied with the fix I came up to, I have to say it's working smoothly.
Basically I wrapped my bottomsheet with a ViewPager and it's not resizing.
I admit this is a hack and I'm hoping someone can provide a more decent answer to this. In the meantime, ViewPager with a single bottomsheet is the way to go.

pamobo0609
  • 812
  • 10
  • 21
0

You can set the height with the below code in On Activity created

view?.viewTreeObserver?.addOnGlobalLayoutListener {
            val rect = Rect()
            view?.getWindowVisibleDisplayFrame(rect)
            val screenHeight = view?.rootView?.height
            val keyPadHeight = screenHeight?.minus(rect.bottom)

            if (screenHeight != null) {
                if (keyPadHeight != 0) {
                    if (view?.paddingBottom != keyPadHeight) {
                        view?.setPadding(0, 0, 0, keyPadHeight!!)
                    }
                } else {
                    if (view?.paddingBottom != 0) {
                        view?.setPadding(0, 0, 0, 0)
                    }
                }

Hope this will work for you.

Naveen rana
  • 101
  • 6