【Android】BottomSheetDialog详解
来源:互联网 发布:关闭miui优化有影响吗 编辑:程序博客网 时间:2024/06/06 01:10
1.简介
BottomSheetDialog是一个自定义的从底部滑入的对话框。市面上很多App都有类似的效果,今天我们实现如下效果:
2.页面布局
从底部弹出view的效果是BottomSheetBehavior来实现的。view必须支持嵌套滚动,而且必须是CoordinatorLayout的直接子类,来看下主题布局。
<?xml version="1.0" encoding="utf-8"?><android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_bottom_sheet" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" app:behavior_hideable="true" > <!--Toolbar--> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Light"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> </android.support.design.widget.AppBarLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/tab_layout" android:gravity="center" android:orientation="vertical" app:behavior_hideable="true" app:layout_behavior="@string/appbar_scrolling_view_behavior" > <Button android:text="显示" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:id="@+id/btn_show" /> <Button android:text="底部按钮" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:id="@+id/btn_bottom" /> </LinearLayout> <!--底部弹出框--> <LinearLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="?actionBarSize" android:layout_alignParentBottom="true" android:background="@android:color/holo_purple" app:behavior_hideable="true" app:behavior_peekHeight="0dp" app:layout_behavior="@string/bottom_sheet_behavior"> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="首页" /> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="课程" /> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="我的" /> </LinearLayout></android.support.design.widget.CoordinatorLayout>
3.点击按钮弹出BottomSheetDialog
创建BottomSheetDialog以及相关的初始化:
WindowManager wm = this.getWindowManager(); int height = wm.getDefaultDisplay().getHeight(); //构造函数的第二个参数可以设置BottomSheetDialog的主题样式// mBottomSheetDialog = new BottomSheetDialog(this,R.style.MyBottomDialog); mBottomSheetDialog = new BottomSheetDialog(this); //导入底部reycler布局 View view = LayoutInflater.from(this).inflate(R.layout.recycler_view, null, false); mBottomSheetDialog.setContentView(view); BottomSheetBehavior mBehavior = BottomSheetBehavior.from((View) view.getParent()); //设置默认弹出高度为屏幕的0.4倍 mBehavior.setPeekHeight((int) (0.4 * height)); //设置点击dialog外部不消失 mBottomSheetDialog.setCanceledOnTouchOutside(false); //RecyclerView相关设置 RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(new MyRecyclerAdapter(this));
点击按钮后,控制显示和隐藏:
if (!mBottomSheetDialog.isShowing()) { mBottomSheetDialog.show();} else { mBottomSheetDialog.dismiss();}
此时点击按钮,如下效果:
问题:此时再次点击显示按钮的话,不会弹出底部框,屏幕会变暗,这是之前我们划下收缩隐藏BottomSheetDialog后,bottomSheetDialogBehavior的状态为隐藏,再次show之后,系统未恢复bottomSheetDialogBehavior的状态,还是隐藏,所以再次点击后页面只是变暗,可以在隐藏时通过设置BottomSheetDialog的状态来解决:
final BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(view);bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
4.弹出普通的View
我们点击显示底部按钮时弹出如下界面:
看下布局文件,CoordinatorLayout里放了一个LinearLayout:
<?xml version="1.0" encoding="utf-8"?><android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/activity_bottom_sheet" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" app:behavior_hideable="true" > <!--底部弹出框--> <LinearLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="?actionBarSize" android:layout_alignParentBottom="true" android:background="@android:color/holo_purple" app:behavior_hideable="true" app:behavior_peekHeight="0dp" app:layout_behavior="@string/bottom_sheet_behavior"> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="首页" /> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="课程" /> <Button android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:text="我的" /> </LinearLayout></android.support.design.widget.CoordinatorLayout>
通过设置LinearLayout的app:layout_behavior属性来设置此布局的行为,设置后Linear会在屏幕的底部:
app:layout_behavior="@string/bottom_sheet_behavior"
控制显示和隐藏:
// 拿到这个tab_layout对应的BottomSheetBehaviormBottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.tab_layout));// 控制展开还是关闭if (mBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) { mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);} else if (mBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_COLLAPSED) { mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);}
5.解决弹出dialog后Android5.0+status bar变黑
自定义BottomSheetDialog,屏幕高度减去状态栏的高度即可:
public class MyBottomSheetDialog extends BottomSheetDialog{ private Activity activity; public MyBottomSheetDialog(@NonNull Context context,Activity activity) { super(context); this.activity = activity; } public MyBottomSheetDialog(@NonNull Context context, @StyleRes int theme,Activity activity) { super(context, theme); this.activity = activity; } protected MyBottomSheetDialog(@NonNull Context context, boolean cancelable, OnCancelListener cancelListener,Activity activity) { super(context, cancelable, cancelListener); this.activity = activity; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); int screenHeight = getScreenHeight(activity); int statusBarHeight = getStatusBarHeight(getContext()); int dialogHeight = screenHeight - statusBarHeight; getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, dialogHeight == 0 ? ViewGroup.LayoutParams.MATCH_PARENT : dialogHeight); } private static int getScreenHeight(Activity activity) { DisplayMetrics displaymetrics = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); return displaymetrics.heightPixels; } private static int getStatusBarHeight(Context context) { int statusBarHeight = 0; Resources res = context.getResources(); int resourceId = res.getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { statusBarHeight = res.getDimensionPixelSize(resourceId); } return statusBarHeight; }}
参考:
1.http://blog.csdn.net/maosidiaoxian/article/details/52288597
2.http://blog.csdn.net/yanzhenjie1003/article/details/51938425
源码下载
- 【Android】BottomSheetDialog详解
- Android Bottom Sheet详解之BottomSheetBehavior与BottomSheetDialog
- BottomSheetDialog
- Android Material Design之BottomSheetDialog
- Android BottomSheetDialog透明问题的解决办法
- Android的Design库---BottomSheetBehavior和BottomSheetDialog
- Android使用BottomSheetBehavior 和 BottomSheetDialog实现底部弹窗
- Android BottomSheetDialog消失后再次无法显示的处理方法
- 【Android】底部弹出框BottomSheet…BottomSheetDialog…BottomSheetDialogFragment实验
- Android 6.0新控件 BottomSheetDialog | 底部对话框 介绍及使用详情
- Android 分享界面,使用BottomSheetDialog(可上拉到顶部,可下拉消失,仿知乎、掘金等)
- BottomSheetDialog 的两个坑
- BottomSheetDialog的使用
- BottomSheetDialog的简单实用
- 自定义 BottomSheetDialog 背景样式
- 设置 BottomSheetDialog 的高度
- BottomSheetDialog小优化
- BottomSheetDialog width无法match_parent
- Lambda表达式
- extern "C" DLL_EXPORT __cdecl与__stdcall
- ELK+Filebeat+Kafka+ZooKeeper 构建海量日志分析平台
- ajax中async true/false的作用
- scrapy框架爬虫将数据保存到MySQL数据库(20170214)
- 【Android】BottomSheetDialog详解
- 35. Search Insert Position
- java进阶--week3-3.2&&3.4--对象数组&&哈希表
- SpringBoot19 之环境变量读取和属性对象的绑定
- 前端培训班出身——吐槽下16年的艰辛
- 面试2
- JavaScript编写简易计算器
- Unittest单元测试框架总结
- vs2013密钥