Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pin a view to bottom of screen in BottomSheetDialog Fragment

I've used BottomSheetDialogFragment in my project and I've designed it as below:

BottomSheetDialogFragment

Target: I'm going to stick the bottom menu of BottomSheetDialog to bottom of the screen, in either mode collapse and expand.

So in BottomSheetDialog layout, I used RelativeLayout for parent and "layout_alignParentBottom" for menu container, As below:

<RelativeLayout 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:id="@+id/bottomSheetContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
tools:context=".MyBottomSheetDialogFragment">

<RelativeLayout
    android:id="@+id/topSection"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true">
    ....
</RelativeLayout>

<android.support.v4.widget.NestedScrollView
    android:id="@+id/descriptionContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/topSection">
    ....
</android.support.v4.widget.NestedScrollView>

<HorizontalScrollView
    android:id="@+id/iconsContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true">
    ....
</HorizontalScrollView>
</RelativeLayout>

But the dialogue is as follows:

BottomSheetDialog

As you can see, the bottom menu is not visible at first.

Can someone help me to solve this problem?

like image 442
roghayeh hosseini Avatar asked Aug 19 '18 08:08

roghayeh hosseini


1 Answers

To solve this, several things came to my mind when I tried, but I did not succeed.

But this finally solved for me by this way:

For collapse mode, I set the bottomSheetBehavior's peekHeight to 1/3 of the screen (with the following code):

    View bottomSheetContainer = dialog.findViewById(R.id.bottomSheetContainer);
    View parent = (View) bottomSheetContainer.getParent();
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) parent.getLayoutParams();
    BottomSheetBehavior bottomSheetBehavior = (BottomSheetBehavior) params.getBehavior();
    View inflatedView = View.inflate(getContext(), R.layout.word_details_bottom_sheet, null);
    inflatedView.measure(0, 0);
    int screenHeight = getActivity().getResources().getDisplayMetrics().heightPixels;

    if (bottomSheetBehavior != null) {
        bottomSheetBehavior.setPeekHeight(screenHeight /3);
    }

So I decided to do it:

1- for collapse mode: bottomSheet container's height = bottomSheetBehavior's peekHeight

2- for expand mode: bottomSheet container's height = full screen Height

So I wrote the following code (full code):

WordDetailsBottomSheet.java

public class WordDetailsBottomSheet extends BottomSheetDialogFragment {

public WordDetailsBottomSheet() { // Required empty public constructor }

@NotNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    BottomSheetDialog dialog = new BottomSheetDialog(getActivity(), 0);
    dialog.setContentView(R.layout.word_details_bottom_sheet);

    View bottomSheetContainer = dialog.findViewById(R.id.bottomSheetContainer);
    View parent = (View) bottomSheetContainer.getParent();
    CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) parent.getLayoutParams();
    BottomSheetBehavior bottomSheetBehavior = (BottomSheetBehavior) params.getBehavior();
    View inflatedView = View.inflate(getContext(), R.layout.word_details_bottom_sheet, null);
    inflatedView.measure(0, 0);
    int screenHeight = getActivity().getResources().getDisplayMetrics().heightPixels;
    int statusBarHeight = getStatusBarHeight();

    if (bottomSheetBehavior != null) {
        bottomSheetBehavior.setPeekHeight(screenHeight / BOTTOM_SHEET_PEEK_HEIGHT_PERCENT);
        bottomSheetContainer.getLayoutParams().height = bottomSheetBehavior.getPeekHeight();
    }

    bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull View view, int newState) {
            switch (newState) {
                case BottomSheetBehavior.STATE_EXPANDED:
                    bottomSheetContainer.getLayoutParams().height = screenHeight-statusBarHeight;
                    break;
                case BottomSheetBehavior.STATE_COLLAPSED:
                    bottomSheetContainer.getLayoutParams().height = bottomSheetBehavior.getPeekHeight();
                    break;
                case BottomSheetBehavior.STATE_HIDDEN:
                    dismiss();
                    break;
                default:
                    break;
            }
        }

        @Override
        public void onSlide(@NonNull View view, float slideOffset) {
        }
    });

    return dialog;
}

public int getStatusBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
    }
}

word_details_bottom_sheet.xml

<RelativeLayout 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:id="@+id/bottomSheetContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
tools:context=".MyBottomSheetDialogFragment">

<RelativeLayout
android:id="@+id/topSection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
....
</RelativeLayout>

<android.support.v4.widget.NestedScrollView
android:id="@+id/descriptionContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/topSection">
....
</android.support.v4.widget.NestedScrollView>

<HorizontalScrollView
android:id="@+id/iconsContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
....
</HorizontalScrollView>
</RelativeLayout>

In the xml file, things that matter are:

1- parent id (android:id="@+id/bottomSheetContainer")

2- iconsContainer align (android:layout_alignParentBottom="true")

enter image description here

like image 50
roghayeh hosseini Avatar answered Nov 09 '22 09:11

roghayeh hosseini