Android使用BottomSheetBehavior 和 BottomSheetDialog实现底部弹窗
16lz
2021-01-26
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();
上个项目效果图:
更多相关文章
- Fragment中跨线程调用控件的问题
- Android(安卓)studio http请求获取数据失败或者获取不到数据原因
- android4.0 上定制状态栏
- 终结篇:Android(安卓)startActivity原理分析(基于Android(安卓)8.
- Android标题栏渐变色,沉寂式状态栏
- Android(安卓)使用ActivityLifecycleCallbacks监听自己应用Activ
- Android(安卓)开发学习笔记(一)—— 四大组件
- Android中判断状态栏是否存在
- android 中如何获取camera当前状态