Material Design系列之BottomSheet详解

BottomSheetBehavior官方文档

BottomSheetDialog官方文档

BottomSheetDialogFragment官方文档

Material Design官方文档Sheets: bottom的介绍

简介

BottomSheet可以理解为底部对话框,类似popwindow实现的效果

BottomSheet有两种类型:

一、没有蒙层,可以对没有遮盖住的地方进行操作,类似百度地图查询路线的页面;

二、有蒙层效果,就是和正常的popwindow使用效果一样了。

使用

compile ‘com.android.support:design:26.0.0-alpha1’

1、BottomSheetBehavior的使用

依赖于CoordinatorLayout和BottomSheetBehavior,需要将底部菜单布局作为CoordinatorLayout的子View,实现简单但不够灵活,适用于底部菜单布局稳定的情况。

<android.support.design.widget.CoordinatorLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context="com.wangshuai.androidui.material.BottomSheetActivity"><include layout="@layout/content_main" /><include layout="@layout/content_bottom_sheet" /></android.support.design.widget.CoordinatorLayout>

content_bottom_sheet布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/ll_content_bottom_sheet"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"app:behavior_hideable="true"app:behavior_peekHeight="50dp"app:layout_behavior="@string/bottom_sheet_behavior"android:background="@color/white"><TextView
        android:layout_width="match_parent"android:layout_height="80dp"android:text="人生若只如初见,何事秋风悲画扇。"android:textSize="20sp"android:gravity="center"/><TextView
        android:layout_width="match_parent"android:layout_height="80dp"android:text="等闲变却故人心,却道故人心易变。"android:textSize="20sp"android:gravity="center"/><TextView
        android:layout_width="match_parent"android:layout_height="80dp"android:text="骊山语罢清宵半,泪雨霖铃终不怨。"android:textSize="20sp"android:gravity="center"/><TextView
        android:layout_width="match_parent"android:layout_height="80dp"android:text="何如薄幸锦衣郎,比翼连枝当日愿。"android:textSize="20sp"android:gravity="center"/></LinearLayout>

其中app:behavior_hideable=”true”表示可以让bottom sheet完全隐藏,默认为false;

app:behavior_peekHeight=”60dp”表示当为STATE_COLLAPSED(折叠)状态的时候bottom sheet残留的高度,默认为0。

app:layout_behavior=”@string/bottom_sheet_behavior”这个一定要设置,不然起不到效果。

通过BottomSheetBehavior控制content_bottom_sheet布局的显示和隐藏

bottomSheetBehavior = BottomSheetBehavior.from(llContentBottomSheet);bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {@Overridepublic void onStateChanged(@NonNull View bottomSheet, int newState) {switch (newState) {case BottomSheetBehavior.STATE_COLLAPSED:Log.e("Bottom Sheet Behaviour", "STATE_COLLAPSED");break;case BottomSheetBehavior.STATE_DRAGGING:Log.e("Bottom Sheet Behaviour", "STATE_DRAGGING");break;case BottomSheetBehavior.STATE_EXPANDED:Log.e("Bottom Sheet Behaviour", "STATE_EXPANDED");break;case BottomSheetBehavior.STATE_HIDDEN:Log.e("Bottom Sheet Behaviour", "STATE_HIDDEN");break;case BottomSheetBehavior.STATE_SETTLING:Log.e("Bottom Sheet Behaviour", "STATE_SETTLING");break;}}@Overridepublic void onSlide(@NonNull View bottomSheet, float slideOffset) {}});case R.id.btn_expand://展开bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);break;case R.id.btn_collapsed://折叠bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);break;case R.id.btn_hide://隐藏bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);break;

Bottom Sheet有五种状态:

  • STATE_COLLAPSED:折叠状态,bottom sheets只在底部显示一部分布局。显示高度可以通过 app:behavior_peekHeight 设置;
  • STATE_DRAGGING:过渡状态,此时用户正在向上或者向下拖动bottom sheet;
  • STATE_SETTLING: 视图从脱离手指自由滑动到最终停下的这一小段时间
  • STATE_EXPANDED: 完全展开的状态
  • STATE_HIDDEN: 隐藏状态。默认是false,可通过app:behavior_hideable属性设置是否能隐藏

这种使用方法是没有蒙层,可以对其他控件进行操作。

2、BottomSheetDialog的使用

BottomSheetDialog的使用就和对话框差不多。会出现蒙层,只能对弹出的页面进行操作。

                if (dialog == null){dialog = new BottomSheetDialog(this);}dialog.setCancelable(false);dialog.setCanceledOnTouchOutside(true);View view =LayoutInflater.from(BottomSheetActivity.this).inflate(R.layout.content_bottom_sheet_dialog,null);TextView tvWechat = view.findViewById(R.id.tv_wechat);tvWechat.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(BottomSheetActivity.this,"微信",Toast.LENGTH_SHORT).show();dialog.dismiss();}});dialog.setContentView(view);dialog.show();

BottomSheetDialog部分源码:

private View wrapInBottomSheet(int layoutResId, View view, ViewGroup.LayoutParams params) {final CoordinatorLayout coordinator = (CoordinatorLayout) View.inflate(getContext(),R.layout.design_bottom_sheet_dialog, null);if (layoutResId != 0 && view == null) {view = getLayoutInflater().inflate(layoutResId, coordinator, false);}FrameLayout bottomSheet = (FrameLayout) coordinator.findViewById(R.id.design_bottom_sheet);mBehavior = BottomSheetBehavior.from(bottomSheet);mBehavior.setBottomSheetCallback(mBottomSheetCallback);mBehavior.setHideable(mCancelable);if (params == null) {bottomSheet.addView(view);} else {bottomSheet.addView(view, params);}// We treat the CoordinatorLayout as outside the dialog though it is technically insidecoordinator.findViewById(R.id.touch_outside).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (mCancelable && isShowing() && shouldWindowCloseOnTouchOutside()) {cancel();}}});// Handle accessibility eventsViewCompat.setAccessibilityDelegate(bottomSheet, new AccessibilityDelegateCompat() {@Overridepublic void onInitializeAccessibilityNodeInfo(View host,AccessibilityNodeInfoCompat info) {super.onInitializeAccessibilityNodeInfo(host, info);if (mCancelable) {info.addAction(AccessibilityNodeInfoCompat.ACTION_DISMISS);info.setDismissable(true);} else {info.setDismissable(false);}}@Overridepublic boolean performAccessibilityAction(View host, int action, Bundle args) {if (action == AccessibilityNodeInfoCompat.ACTION_DISMISS && mCancelable) {cancel();return true;}return super.performAccessibilityAction(host, action, args);}});bottomSheet.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View view, MotionEvent event) {// Consume the event and prevent it from falling throughreturn true;}});return coordinator;}

由源码可知,BottomSheetDialog的setContentView最终是被CoordinatorLayout包裹住。

3、BottomSheetDialogFragment的使用

BottomSheetDialogFragment的使用和fragment一样。可以帮助我们实现全屏的BottomSheet展示效果

CustomFragmentDialog fragmentDialog = new CustomFragmentDialog();
fragmentDialog.show(getSupportFragmentManager(),"CustomFragmentDialog");public class CustomFragmentDialog extends BottomSheetDialogFragment {private ArrayList<String> list = new ArrayList<>();public CustomFragmentDialog() {}@Nullable@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View view = inflater.inflate(R.layout.content_bottom_sheet_fragment_dialog,container, false);initViews(view);return view;}private void initViews(View view) {for (int i = 0;i < 100;i++){list.add("条目"+i);}RecyclerView recyclerView = view.findViewById(R.id.rv_item);recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));RecyclerViewAdapter adapter = new RecyclerViewAdapter(list);recyclerView.setAdapter(adapter);}}/*** 全屏显示*/
public class FullSheetDialogFragment extends BottomSheetDialogFragment{private BottomSheetBehavior mBehavior;private ArrayList<String> list = new ArrayList<>();public FullSheetDialogFragment() {}@Overridepublic Dialog onCreateDialog(Bundle savedInstanceState){BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);View view = View.inflate(getContext(), R.layout.content_bottom_sheet_fragment_dialog, null);initViews(view);dialog.setContentView(view);mBehavior = BottomSheetBehavior.from((View) view.getParent());return dialog;}private void initViews(View view) {for (int i = 0;i < 100;i++){list.add("条目"+i);}RecyclerView recyclerView = view.findViewById(R.id.rv_item);recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));RecyclerViewAdapter adapter = new RecyclerViewAdapter(list);recyclerView.setAdapter(adapter);}@Overridepublic void onStart(){super.onStart();mBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);//全屏展开}}
使用bottom sheet的问题

BottomSheetDialog沉浸式的一些坑

解决使用BottomSheetDialog时状态栏变黑的问题

Github示例代码

Material Design系列之BottomSheet详解相关推荐

  1. Material Design系列之BottomNavigationView详解

    Material Design系列之BottomNavigationView详解 Material Design官方文档Bottom navigation的介绍 BottomNavigationVie ...

  2. Android Material Design 系列之 BottomNavigationView + ViewPager + Fragment + BadgeView 开发详解

    前言 BottomNavigationView 是 Material Design 提供的一个标准底部导航栏的实现,可以轻松的实现导航栏菜单之间的切换与浏览.底部导航使用户更方便的查看和切换最高层级的 ...

  3. Docker系列07—Dockerfile 详解

    Docker系列07-Dockerfile 详解 1.认识Dockerfile 1.1 镜像的生成途径 基于容器制作  dockerfile,docker build 基于容器制作镜像,已经在上篇Do ...

  4. mongo 3.4分片集群系列之六:详解配置数据库

    这个系列大致想跟大家分享以下篇章: 1.mongo 3.4分片集群系列之一:浅谈分片集群 2.mongo 3.4分片集群系列之二:搭建分片集群--哈希分片 3.mongo 3.4分片集群系列之三:搭建 ...

  5. android夜间模式揭露动画,Android Material Design系列之夜间模式

    今天我们讲讲夜间模式的实现,这篇文章的名字应该叫:<Android Material Design系列之夜间模式>.在Android 5.0 之后,实现夜间模式并非很难了,支持的5.0库提 ...

  6. ftm模块linux驱动,飞思卡尔k系列_ftm模块详解.doc

    飞思卡尔k系列_ftm模块详解 1.5FTM模块1.5.1 FTM模块简介FTM模块是一个多功能定时器模块,主要功能有,PWM输出.输入捕捉.输出比较.定时中断.脉冲加减计数.脉冲周期脉宽测量.在K1 ...

  7. React Native按钮详解|Touchable系列组件使用详解

    转载自:http://www.devio.org/2017/01/10/React-Native按钮详解-Touchable系列组件使用详解/ 在做App开发过程中离不了的需要用户交互,说到交互,我们 ...

  8. android 按钮带图标 阴影_Android Material Design系列之FloatingActionButton和Snackbar

    今天主讲的Material Design系列的两个控件都不难,所以一起讲了,分别是FloatingActionButton和Snackbar.这个系列都是主讲的Material Design风格的控件 ...

  9. React 源码系列 | React Context 详解

    目前来看 Context 是一个非常强大但是很多时候不会直接使用的 api.大多数项目不会直接使用 createContext 然后向下面传递数据,而是采用第三方库(react-redux). 想想项 ...

  10. Landsat系列数据级别详解

    Landsat系列数据级别详解 转载自此文:https://www.cnblogs.com/icydengyw/p/12056211.html 一.Landsat Collection 1 Lands ...

最新文章

  1. angular具体用法及代码
  2. Vim 实用技术,第 2 部分: 常用插件
  3. html加javascript和canvas类似超级玛丽游戏
  4. action怎么获得 ajax date参数_ajax()gt;load()事件的新用法!!!
  5. (3)[wp7数据存储] WP7 IsolatedStorage系列篇——通过XmlSerializer读写XML文件 [复制链接]...
  6. 图的表示方法和C++实现
  7. Elasticsearch 简介入门
  8. 数据仓库被淘汰了?都怪数据湖
  9. VPC-阿里云专有网络 Virtual Private Cloud
  10. java并发令牌机制,redis令牌机制实现秒杀
  11. python with open as yaml_python – pyyaml并仅使用字符串引号
  12. 3月19日 视觉里程计,PnP方法对两帧求解,BA优化的直观理解
  13. android无线投屏到电视盒子,如何把电脑视频投屏到智能电视/电视盒子上?
  14. 【英语:基础进阶_听口实战运用】D5.听力对话训练
  15. 2021react复习
  16. 门面模式、调停者模式、责任链模式
  17. [C#入门] 函数 | 方法
  18. rls最小二乘法 c语言,RLS递归最小二乘(最新整理)
  19. 4个工具,个个都是精品!修复图片视频画质超好用
  20. Win10的几个实用技巧系列之win10和win8系统哪个好用、系统任务栏和窗口假死的解决方法

热门文章

  1. 第八章 软件项目团队管理
  2. docker安装php拓展
  3. 美团点评2020校园招聘商业分析师一面(2019.9.5)
  4. Python地学分析 — 通过GPS数据分析鸟类行踪 07
  5. 有证无车的程序猿如何查询档案编号、添加电子驾驶证(支付宝、微信)
  6. SSM整合开发实战-poi导入导出excel-前言
  7. lilo是什么意思_Lilo
  8. qq三国华容道算法(拼图问题,8数码问题?)
  9. ADSL上网常见故障解答
  10. 计算机在智能交通应用,计算机信息技术在智能交通系统中的应用