Android使用BottomSheetBehavior 和 BottomSheetDialog实现底部弹窗

Posted 碎格子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android使用BottomSheetBehavior 和 BottomSheetDialog实现底部弹窗相关的知识,希望对你有一定的参考价值。

BottomSheetBehavior 和 BottomSheetDialog都是design包里的。这两种配合使用可以实现底部弹窗效果。

BottomSheetDialog使用方法和正常的弹框是一样的,他的内部是通过BottomSheetBehavior来控制弹框的收起和弹出等状态。

BottomSheetBehavior的状态:

    /**
     * The bottom sheet is dragging.
     */
    public static final int STATE_DRAGGING = 1;

    /**
     * The bottom sheet is settling.
     */
    public static final int STATE_SETTLING = 2;

    /**
     * The bottom sheet is expanded.
     */
    public static final int STATE_EXPANDED = 3;

    /**
     * The bottom sheet is collapsed.
     */
    public static final int STATE_COLLAPSED = 4;

    /**
     * The bottom sheet is hidden.
     */
    public static final int STATE_HIDDEN = 5;

使用方法

跟正常Dialog的使用是一样一样的:

BottomSheetDialog sheetDialog = new BottomSheetDialog();
sheetDialog.setContentView(view);
sheetDialog.show();

遇到的坑

这样写虽然非常简单,但是却有一个大坑。当我们把弹框弹出来之后可以通过点击弹框外部和向下拖拽弹框使弹框消失。而使用向下拖拽的方法虽然使弹框消失了,但下一次再show的时候,遮罩效果出来了,但是弹框却没有弹出来。

原因

原因是当我们向下拖拽时,BottomSheetBehavior的状态变为了STATE_HIDDEN,而BottomSheetDialog在内部用BottomSheetBehavior对状态做了处理,再次show之后,系统未恢复bottomSheetDialogBehavior的状态,还是隐藏:


    private BottomSheetBehavior.BottomSheetCallback mBottomSheetCallback
            = new BottomSheetBehavior.BottomSheetCallback() 
        @Override
        public void onStateChanged(@NonNull View bottomSheet,
                @BottomSheetBehavior.State int newState) 
            if (newState == BottomSheetBehavior.STATE_HIDDEN) 
                cancel();
            
        

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

解决办法

//通过获得design_bottom_sheet的视图来获取behavior,修改状态
    View view1 = sheetDialog.getDelegate().findViewById(android.support.design.R.id.design_bottom_sheet);
    final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(view1);
    //实现对状态改变的监听
    bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() 
        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) 
            if (newState == BottomSheetBehavior.STATE_HIDDEN) 
                sheetDialog.dismiss();
        //设置BottomSheetBehavior状态为STATE_COLLAPSED             
        bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
            
         

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

         
     );

代码实现

if (sheetDialog == null) 
    sheetDialog = new BottomSheetDialog(getContext());
    sheetDialog.setContentView(recyclerView);
    View view1 = sheetDialog.getDelegate().findViewById(android.support.design.R.id.design_bottom_sheet);
    final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(view1);
    bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() 
        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) 
            if (newState == BottomSheetBehavior.STATE_HIDDEN) 
                sheetDialog.dismiss();
                bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
            
         

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

         
     );

sheetDialog.show();

上个项目效果图:



以上是关于Android使用BottomSheetBehavior 和 BottomSheetDialog实现底部弹窗的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )

Android之SharedPreferences使用

想要使用cordova/android禁用android的HardBack按钮

如何在Mac中使用Android SDK

何时使用“?android”或“@android”?

Android 安装包优化Android 中使用 SVG 图片 ( 使用 appcompat 支持库兼容 5.0 以下版本的 Android 系统使用矢量图 )