How to use BottomSheetDialog?

前端 未结 5 448
暖寄归人
暖寄归人 2021-02-03 19:41

I want to try BottomSheetDialog introduced in Android Support Library 23.2 but it doesn\'t seem to work correctly. Here is what the doc says:

相关标签:
5条回答
  • 2021-02-03 20:15

    Instead of having a separate class, you can simply create an instance for BottomSheetDialog in your Activity/Fragment like following and you can use it. It is very easier and simpler I think.

    val dialog = BottomSheetDialog(this)
    val bottomSheet = layoutInflater.inflate(R.layout.bottom_sheet, null)
    
    bottomSheet.buttonSubmit.setOnClickListener { dialog.dismiss() }
    
    dialog.setContentView(bottomSheet)
    dialog.show()
    

    For brief tutorial you can refer here

    0 讨论(0)
  • 2021-02-03 20:27

    I was expriencing the same issue, dimmed background and content not visible. Here is how I managed to workaround it by setting the content view in setupDialog() hidden method.

    public class CustomBottomSheetDialogFragment extends BottomSheetDialogFragment {
    
        private TextView mOffsetText;
        private TextView mStateText;
        private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {
    
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                setStateText(newState);
                if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                    dismiss();
                }
    
            }
    
            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                setOffsetText(slideOffset);
            }
        };
        private LinearLayoutManager mLinearLayoutManager;
        private ApplicationAdapter mAdapter;
    
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            return super.onCreateDialog(savedInstanceState);
        }
    
        @Override
        public void onViewCreated(View contentView, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(contentView, savedInstanceState);
        }
    
        @Override
        public void setupDialog(Dialog dialog, int style) {
            super.setupDialog(dialog, style);
            View contentView = View.inflate(getContext(), R.layout.bottom_sheet_dialog_content_view, null);
            dialog.setContentView(contentView);
           mBottomSheetBehavior = BottomSheetBehavior.from(((View) contentView.getParent()));
            if (mBottomSheetBehavior != null) {
                mBottomSheetBehavior.setBottomSheetCallback(mBottomSheetBehaviorCallback);   
            }
            mOffsetText = (TextView) contentView.findViewById(R.id.offsetText);
            mStateText = (TextView) contentView.findViewById(R.id.stateText);
        }
    
    }
    

    And the layout:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
    
        <TextView
            android:id="@+id/offsetText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/black" />
    
        <TextView
            android:id="@+id/stateText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@android:color/black" />
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
    
    0 讨论(0)
  • 2021-02-03 20:30

    It started to work when I set fixed height for my TextView (200dp), although for some height values it still behaves incorrectly. Obviously it's an issue of support lib. There are already few reports related to BottomSheetDialog in the bug tracker:

    https://code.google.com/p/android/issues/detail?id=201793&sort=-opened&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened

    https://code.google.com/p/android/issues/detail?id=201826

    0 讨论(0)
  • 2021-02-03 20:33

    Here's the issue on code.google.com https://code.google.com/p/android/issues/detail?id=201793

    An issue some users are seeing boils down to the FrameLayout that wraps our content view being centered vertically. The BottomSheetBehavior only works if this view is top aligned. I haven't figured out what causes the FrameLayout to become centered vertically yet, but here's a possible workaround:

    View contentView = ...
    // You may have to measure your content view first.
    dialog.setContentView(contentView);
    
    // Change this to a percentage or a constant, whatever you want to do.
    // The default is 1024 - any views smaller than this will be pulled off 
    // the bottom of the screen.
    float peekHeight = contentView.getMeasuredHeight();
    
    View parent = (View)contentView.getParent();
    BottomSheetBehavior behavior = BottomSheetBehavior.from(parent);
    behavior.setPeekHeight(peekHeight);
    CoordinatorLayout.LayoutParams layoutParams = 
       (CoordinatorLayout.LayoutParams)parent.getLayoutParams();
    layoutParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
    
    0 讨论(0)
  • 2021-02-03 20:38

    This is the layout file of BottomSheetDialog.

    <android.support.design.widget.CoordinatorLayout
        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="match_parent"
        android:soundEffectsEnabled="false">
    
    <FrameLayout
            android:id="@+id/design_bottom_sheet"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            app:layout_behavior="@string/bottom_sheet_behavior"
            style="?attr/bottomSheetStyle"/>
    
    </android.support.design.widget.CoordinatorLayout>
    

    Your content view is inside the view design_bottom_sheet, it will be positioned center vertically by CoordinatorLayout, and BottomSheetBehavior will offset it.

    mParentHeight = parent.getHeight();
    mMinOffset = Math.max(0, mParentHeight - child.getHeight());
    mMaxOffset = mParentHeight - mPeekHeight;
    if (mState == STATE_EXPANDED) {
        ViewCompat.offsetTopAndBottom(child, mMinOffset);
    } else if (mHideable && mState == STATE_HIDDEN) {
        ViewCompat.offsetTopAndBottom(child, mParentHeight);
    } else if (mState == STATE_COLLAPSED) {
        ViewCompat.offsetTopAndBottom(child, mMaxOffset);
    }
    

    It intented to positon design_bottom_sheet at mMaxOffset, but actually the initial getTop of the child view is not 0, but (mParentHeight - childHeight) / 2, so you view if offset more than the desired offset.

    Find the view design_bottom_sheet and set its gravity to Gravity.TOP | Gravity.CENTER_HORIZONTAL will fix it. But, if the childHeight is less than mPeekHeight, there will be blank area below you content view.

    However, if peekHeight > childHeight, the mMaxOffset will less than mMinOffset, which will cause weird behavior.

    Maybe the code should be changed to

    mMaxOffset = Math.max((mParentHeight - mPeekHeight), mMinOffset);
    

    insted of

    mMaxOffset = mParentHeight - child.getHeight();
    
    0 讨论(0)
提交回复
热议问题