简体   繁体   中英

Android Bottom Sheet Modal (Dialog) doesn't open completely

I am trying to show a bottom sheet dialog in my app on a button click. But the dialog is opening partially. I would like to open the dialog completely on button click.

I have tried following code.

MainActivity.java

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    View showModalBottomSheet = findViewById(R.id.as_modal);
    showModalBottomSheet.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //Initializing a bottom sheet
            BottomSheetDialogFragment bottomSheetDialogFragment = new CustomBottomSheetDialogFragment();

            //show it
            bottomSheetDialogFragment.show(getSupportFragmentManager(), bottomSheetDialogFragment.getTag());
        }
    });
}
}

CustomBottomSheetDialogFragment.java

public class CustomBottomSheetDialogFragment extends BottomSheetDialogFragment {


@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {

    @Override
    public void onStateChanged(@NonNull View bottomSheet, int newState) {
        if (newState == BottomSheetBehavior.STATE_HIDDEN) {
            dismiss();
        }
    }

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

@Override
public void setupDialog(Dialog dialog, int style) {
    super.setupDialog(dialog, style);
    View contentView = View.inflate(getContext(), R.layout.dialog_modal, null);
    dialog.setContentView(contentView);
    CoordinatorLayout.LayoutParams layoutParams =
            (CoordinatorLayout.LayoutParams) ((View) contentView.getParent()).getLayoutParams();
    CoordinatorLayout.Behavior behavior = layoutParams.getBehavior();
    if (behavior != null && behavior instanceof BottomSheetBehavior) {
        ((BottomSheetBehavior) behavior).setBottomSheetCallback(mBottomSheetBehaviorCallback);
    }
}
}

activity_main.xml

  <?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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.support.design.widget.AppBarLayout
    android:id="@+id/app_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

</android.support.design.widget.AppBarLayout>

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <Button
        android:id="@+id/as_modal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/activity_horizontal_margin"
        android:text="@string/modal" />

</android.support.v4.widget.NestedScrollView>

Here you can find the link to the project:

Github Project Link

Current Behaviour:

当前行为的屏幕截图

At this lines in the setUpDialog method can solve the problem

 BottomSheetDialog d = (BottomSheetDialog) dialog;
 FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet);
 BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);

That method write in your CustomBottomSheetDialogFragment in onCreate method

getDialog().setOnShowListener(new DialogInterface.OnShowListener() {
        @Override
        public void onShow(DialogInterface dialog) {
            BottomSheetDialog d = (BottomSheetDialog) dialog;
            FrameLayout bottomSheet =  d.findViewById(R.id.design_bottom_sheet);
            CoordinatorLayout lyout = (CoordinatorLayout) bottomSheet.getParent();
            BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
            behavior.setPeekHeight(bottomSheet.getHeight());
            lyout.getParent().requestLayout();
        }
    });

The BottomSheetDialogFragment and BottomSheetDialog in Android Support Library Vesion 23.2.0 had some issues.

You can check this doc in Android Support Library, revision 23.2.1 (March 2016) section.

So, the solution is to update your com.android.support:design version to above 23.2.0. (23.2.1、23.3.0、23.4.0 whatever the new version).

I have tested your code in the new version. It worked normally.

Hope it help.

你应该为你的行为设置peekHeight

I have followed these steps, this helped me for BottomSheetDialog dialog .

Step1: To create a BottomSheetBehaviour , you need the FrameLayout of the dialog which exists by default.

FrameLayout bottomSheet = dialog.findViewById(android.support.design.R.id.design_bottom_sheet);

if you are using androidx, use

FrameLayout bottomSheet = dialog.findViewById(com.google.android.material.R.id.design_bottom_sheet);

Step2: Set bottom sheet behaviour to Expanded state and also set a peek height

BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
behavior.setPeekHeight(screenHeight / 2);
behavior.setHideable(false);

Step3: Don't allow dialog to cancel on touch outside

dialog.setCanceledOnTouchOutside(false);

Note: You can calculate screenHeght dynamically using DisplayMetrics.

DisplayMetrics screenMetrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(screenMetrics);
            int screenHeight = screenMetrics.heightPixels;
            int screenWidth = screenMetrics.widthPixels;

add something like this to onCreateView method:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    getDialog().setOnShowListener(new DialogInterface.OnShowListener() {
        @Override
        public void onShow(DialogInterface dialog) {
            BottomSheetDialog d = (BottomSheetDialog) dialog;
            View bottomSheetInternal = d.findViewById(android.support.design.R.id.design_bottom_sheet);
            BottomSheetBehavior.from(bottomSheetInternal).setState(BottomSheetBehavior.STATE_EXPANDED);
        }
    });
    return inflater.inflate(R.layout.your_bottomsheet_content_layout, container, false);
}

for AndroidX use

com.google.android.material.R.id.design_bottom_sheet

instead of

android.support.design.R.id.design_bottom_sheet

Do not use fragment use BottomSheetDialog. Sample demo uploaded to https://github.com/bita147/BottomSheetDialog

For Model dialog just set

bottomshetDialod.setCanceledOnTouchOutside(false);

Works for me.

Same thing was happening with me. The weird reason behind it was Toolbar If you remove the toolbar then bottomsheet will be shown on full screen.

I don't know the reason behind it. But after removing Toolbar it was working fine. You can try that.

This code works for me.

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

    dialog!!.setOnShowListener { dialog ->
        val d = dialog as BottomSheetDialog
        val bottomSheetInternal: FrameLayout? =
            d.findViewById(com.google.android.material.R.id.design_bottom_sheet)
        BottomSheetBehavior.from(bottomSheetInternal!!).state =
            BottomSheetBehavior.STATE_EXPANDED
    }
    val view = inflater.inflate(R.layout.bottom_sheet_modal, container, false)

    return view
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM