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创建底部弹窗效果,详细阐述了BottomSheetBehavior的状态变化,使用步骤,以及在实际使用中遇到的坑和解决方案。内容包括 BottomSheetDialog的初始化,状态管理,以及修复下拉隐藏后无法重新显示的问题。
1万+

被折叠的 条评论
为什么被折叠?



