简体   繁体   中英

BottomSheetDialogFragment doesn't show full height in landscape mode

I am using BottomSheetDialogFragment in my activity, the dialog shows full height in portrait mode but doesn't when I switch to landscape mode.

人像模式

横向模式

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        CustomBottomSheetDialog customBottomSheetDialog = new CustomBottomSheetDialog();
        customBottomSheetDialog.show(getSupportFragmentManager(),customBottomSheetDialog.getTag());
    }
}

CustomBottomSheetDialog

public class CustomBottomSheetDialog extends BottomSheetDialogFragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return View.inflate(getContext(), R.layout.view_config, null);
    }
}

CustomBottomSheetDialog layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:background="#fdf107"
              android:layout_height="wrap_content">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="196dp"
        android:gravity="center"
        android:textColor="@color/colorAccent"
        android:text="BottomSheetDialogFragment"/>

</LinearLayout>

in landscape mode, i have to drag BottomSheetDialogFragment to see the whole content.

the solution for this issue is.

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (Build.VERSION.SDK_INT < 16) {
                view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            } else {
                view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
            BottomSheetDialog dialog = (BottomSheetDialog) getDialog();
            FrameLayout bottomSheet = (FrameLayout)
            dialog.findViewById(android.support.design.R.id.design_bottom_sheet);
            BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
            behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
            behavior.setPeekHeight(0); // Remove this line to hide a dark background if you manually hide the dialog.
        }
    });
}

Thanks to @avez raj and Prevent dismissal of BottomSheetDialogFragment on touch outside I wrote in onCreateDialog() .

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

    dialog.setOnShowListener {
        val bottomSheet = dialog.findViewById<View>(
            com.google.android.material.R.id.design_bottom_sheet) as? FrameLayout
        val behavior = BottomSheetBehavior.from(bottomSheet)
        behavior.state = BottomSheetBehavior.STATE_EXPANDED
    }

    return dialog
}

Currently I use MakinTosH solution, it is shorter.

This worked for me and was the cleanest approach:

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    val dialog = BottomSheetDialog(requireContext(), theme)
    dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
    return dialog
}

The ViewTreeObserver solution did not work for me, but I found a superior solution here and converted it to Kotlin. This one doesn't have the expensive computational waste which comes with a ViewTreeObserver and nicely bundles the functionality into the class.

class ExpandedBottomSheetDialog(context: Context) : BottomSheetDialog(context) {

    override fun show() {
        super.show()
        // androidx should use: com.google.android.material.R.id.design_bottom_sheet
        val view = findViewById<View>(R.id.design_bottom_sheet)
        view!!.post {
            val behavior = BottomSheetBehavior.from(view)
            behavior.setState(BottomSheetBehavior.STATE_EXPANDED)
        }
    }
}

You can simply do the following:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    dialog?.let {
        val sheet = it as BottomSheetDialog
        sheet.behavior.state = BottomSheetBehavior.STATE_EXPANDED
    }

    // rest of your stuff
}

This is a problem of gestureInsetBottomIgnored . For landscape this flag is false, but for portrait is true.

Any reason why after adding `onConfigurationChanged, it did not work(need to drag it again in landscape)

// support when screen rotate, resize etc.
override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    rvLayoutManager.spanCount = getSpanCount()
    rvLayoutManager.requestLayout()
}

private fun getSpanCount(): Int {
    val widthPx = resources.displayMetrics.widthPixels
    val profileWidth = activity!!.resources.getDimension(R.dimen.profile_width)
    return Math.floor((widthPx / profileWidth).toDouble()).toInt()
}

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