概述

日常app开发中,对话框无疑是交互非常方便的载体,无论是app更新提示对话框还是评论列表对话框,可以减少不必要的页面跳转。今天我们的主题是Design Support Library中新增的控件BottomSheetDialog,顾名思义,就是底部弹出,下滑关闭的对话框。
没图没真香,我们先来看看效果图:

效果图

网易云效果

demo效果(丑了点,见谅)

基本使用

1、导入依赖

implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'

2、编写代码

BottomSheetDialog需要导入support:design包,我们创建TestBottomSheetDialogFragment.class继承DialogFragment

public class TestBottomSheetDialogFragment extends DialogFragment {@NonNull@Overridepublic Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {//返回BottomSheetDialog的实例return new BottomSheetDialog(this.getContext());}@Overridepublic void onStart() {super.onStart();BottomSheetDialog dialog = (BottomSheetDialog) getDialog();//注意控件id别搞错FrameLayout bottomSheet = dialog.getDelegate().findViewById(android.support.design.R.id.design_bottom_sheet);if (bottomSheet != null) {CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) bottomSheet.getLayoutParams();//设置弹窗最大高度layoutParams.height = getPeekHeight();bottomSheet.setLayoutParams(layoutParams);BottomSheetBehavior<FrameLayout> behavior = BottomSheetBehavior.from(bottomSheet);//peekHeight即弹窗的最大高度behavior.setPeekHeight(getPeekHeight());// 初始为展开状态behavior.setState(BottomSheetBehavior.STATE_EXPANDED);}}/*** 弹窗高度,默认为屏幕高度的四分之三* 子类可重写该方法返回peekHeight** @return height*/protected int getPeekHeight() {int peekHeight = getResources().getDisplayMetrics().heightPixels;//设置弹窗高度为屏幕高度的3/4return peekHeight - peekHeight / 3;}@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {View view = inflater.inflate(R.layout.dialog_bottom_sheet,container,false);RecyclerView recyclerView = view.findViewById(R.id.rv);RvAdapter adapter = new RvAdapter(getData());recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));recyclerView.setAdapter(adapter);recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),LinearLayoutManager.VERTICAL));return view;}private List<String> getData(){List<String> list = new ArrayList<>();for (int i=0;i<20;i++){list.add("this is item in "+i);}return list;}}

对应的dialog_bottom_sheet.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/colorPrimary"><TextViewandroid:id="@+id/tv_comment_num"android:layout_width="wrap_content"android:layout_height="40dp"android:gravity="center"android:text="20首歌"android:textColor="#333333"android:textSize="17sp"android:textStyle="bold"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"/><Viewandroid:id="@+id/view_line"android:layout_width="0dp"android:layout_height="1dp"android:background="@color/design_default_color_primary_dark"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/tv_comment_num"/><ImageViewandroid:id="@+id/iv_close"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginRight="20dp"android:src="@android:drawable/ic_menu_close_clear_cancel"app:layout_constraintBottom_toBottomOf="@+id/tv_comment_num"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintTop_toTopOf="@+id/tv_comment_num"/><android.support.v7.widget.RecyclerViewandroid:id="@+id/rv"android:layout_width="0dp"android:layout_height="0dp"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@id/view_line"/></android.support.constraint.ConstraintLayout>

列表adapter

public class RvAdapter extends RecyclerView.Adapter<RvAdapter.RvViewHolder> {private List<String> mList;public RvAdapter(List<String> list) {mList = list;}@NonNull@Overridepublic RvViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(android.R.layout.simple_list_item_activated_1,viewGroup,false);return new RvViewHolder(itemView);}@Overridepublic void onBindViewHolder(@NonNull RvViewHolder viewHolder, int position) {viewHolder.mTextView.setText(mList.get(position));}@Overridepublic int getItemCount() {return mList.size();}class RvViewHolder extends RecyclerView.ViewHolder{TextView mTextView;RvViewHolder(@NonNull View itemView) {super(itemView);mTextView = itemView.findViewById(android.R.id.text1);}}}

抽取共同代码

上面的TestBottomSheetDialogFragment代码量还是有点多的,我们可以新建BaseBottomSheetDialogFragment,抽取共同的代码

public abstract class BaseBottomSheetDialogFragment extends DialogFragment {protected View mRootView;@NonNull@Overridepublic Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {return new BottomSheetDialog(this.getContext());}@Overridepublic void onStart() {super.onStart();BottomSheetDialog dialog = (BottomSheetDialog) getDialog();FrameLayout bottomSheet = dialog.getDelegate().findViewById(android.support.design.R.id.design_bottom_sheet);if (bottomSheet != null) {CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) bottomSheet.getLayoutParams();layoutParams.height = getPeekHeight();bottomSheet.setLayoutParams(layoutParams);BottomSheetBehavior<FrameLayout> behavior = BottomSheetBehavior.from(bottomSheet);behavior.setPeekHeight(getPeekHeight());// 初始为展开状态behavior.setState(BottomSheetBehavior.STATE_EXPANDED);}}/*** 弹窗高度,默认为屏幕高度的四分之三* 子类可重写该方法返回peekHeight** @return height*/protected int getPeekHeight() {int peekHeight = getResources().getDisplayMetrics().heightPixels;return peekHeight - peekHeight / 3;}/*** 返回布局 resId** @return layoutId*/protected abstract int getLayoutRes();/*** 初始化数据** @param savedInstanceState bundle*/protected abstract void initData(Bundle savedInstanceState);@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater,@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {mRootView = inflater.inflate(getLayoutRes(), container, false);return mRootView;}@Overridepublic void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);initData(savedInstanceState);}}

然后TestBottomSheetDialogFragment继承BaseBottomSheetDialogFragment

public class TestBottomSheetDialogFragment extends BaseBottomSheetDialogFragment {@Overrideprotected int getLayoutRes() {return R.layout.dialog_bottom_sheet;}@Overrideprotected void initData(Bundle savedInstanceState) {RecyclerView recyclerView = mRootView.findViewById(R.id.rv);recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),LinearLayoutManager.VERTICAL));RvAdapter adapter = new RvAdapter(getData());recyclerView.setAdapter(adapter);}private List<String> getData(){List<String> list = new ArrayList<>();for (int i=0;i<20;i++){list.add("this is item in "+i);}return list;}}

子类代码量是不是瞬间少了很多,我们来运行下看看效果

OK,至此实现了网易云的弹窗效果!

总结

1、BottomSheetDialog默认弹窗高度是覆盖整个屏幕的,我们在behavior.setPeekHeight(getPeekHeight());中指定弹窗高度为getPeekHeight(),具体看参考BottomSheetBehavior源码;
2、Google官网建议开发者使用DialogFragment,我们直接继承DialogFragment,然后返回BottomSheetDialog的实例,再指定弹窗的最大高度就OK。

Android BottomSheetDialog使用,实现网易云歌单底部弹窗相关推荐

  1. Android自定义view之网易云推荐歌单界面

    系列文章目录 Android自定义view之网易云推荐歌单界面 文章目录 系列文章目录 前言 一.实现 1.自定义一个圆角图片控件(也可直接使用第三方框架) 2.进行布局摆设 3.图片切换动画效果 二 ...

  2. 网易云歌单重合率2.0

    前言: 之前写过一个小工具输入网易云音乐上的昵称,即可查看两人喜欢的音乐中,有哪些是相同的,重合率有多少. 感兴趣的可以看这里:网易云歌单重合率1.0 但是之前的版本存在几个问题: 速度慢,这个其实是 ...

  3. Python爬虫-selenium爬取网易云歌单

    文章目录 (一)工欲善其事必先利其器-安装工具 Selenium 浏览器 (二)实战 (一)工欲善其事必先利其器-安装工具 Selenium Selenium是一个强大的网络数据采集工具,其最初是为网 ...

  4. Python爬虫之网易云歌单音频爬取(解决urlretrieve爬取文件不能播放问题)

    网易云歌单音频爬取 写在前面:最近学习爬虫,对小说和图片都进行过简单爬取,所以打算爬取音频,但是其中遇到点问题也解决了,写下博客记录并希望对大家也有帮助. 爬取对象:对于目前主流的几个音频播放网站,我 ...

  5. 茶云个人导航系统v1.2源码 带后台+网易云歌单播放功能+腾讯智能在线客服功能

    这是一款好看的个人导航网自带后台,本导航系统由奶茶二次开发而成,后添加各种美化,后台自定义添加导航,背景,源码集成网易云歌单播放和腾讯智能在线客服功能使源码更显一个档次! 温馨提示,如果涉及到授权,源 ...

  6. iTunes音乐导入过程记录(专辑图片、歌手修改,iTunes使用,网易云歌单批量下载)

    所需工具 1.iTunes 2.音乐标签修改器. 3.下载好的音乐 网易云歌单在线下载. 4.一点耐心 详细步骤 1.先调整一下iTunes中的音乐存储位置 菜单栏选编辑-偏好设置-高级 更改iTun ...

  7. 网易云歌单歌曲实时拉取

    网易云歌单歌曲实时拉取 最近个人公众号Mozi的bug日志上线了新的音乐推送API,下面来讲讲推送的实现过程. 一.抓取目的 抓取歌单中的歌曲列表,并提取对应歌曲的外链.歌曲名单以及作者名 测试歌曲外 ...

  8. [数据分析笔记] 网易云歌单分析系列02—pyecharts柱状图

    文章目录 0.前言 1.百分比堆叠柱状图 1.1 导入包,连接数据库 1.2 查看数据 1.3 数据预处理 1.4 生成图表 2.复合柱状图和折线图 2.1 数据预处理 2.2 生成图表 3.竖直缩放 ...

  9. Python 将网易云歌单迁移到QQ音乐

    最近,网易云音乐越来越多的歌曲变灰了,许多我以前喜欢听的音乐都消失在云端,非常可惜.最近我还是想听回以前的歌曲,于是只能使用有那些歌曲版权的QQ音乐,麻烦的是,QQ音乐没有我在网易云音乐的歌单,两个软 ...

最新文章

  1. Wasserstein距离在生成模型中的应用
  2. 关于《在Windows与.NET平台上的持续交付实践》的问答录
  3. php发送验证码短信,php发送短信验证码
  4. skywalking 源码解析——多线程变量传递 EnhancedInstance
  5. filter java oauth_java – 带有自定义安全过滤器的Spring Boot OAuth2
  6. Web前端行业普遍底薪20K,还有项目提成,你达到了么?教你这一招
  7. VS2013显示行号及显示程序汇编代码
  8. CSS相关知识点:6种清除浮动和BFC
  9. Android中当item数量超过一定大小RecyclerView高度固定
  10. Matable实现利用互相关函数求相位差
  11. 模糊数学与matlab
  12. 调用QQ/TIM算法实现获取当前登陆账号和ClientKey
  13. php第三方支付sdk,第三方支付 SDK
  14. android修改shell串口号,[Note] 2021-01-15 Android shell/串口中使用 wpa_cli 连接Wi-Fi
  15. 如何区别测试计划和测试方案
  16. x是小于9的非负数的matlab,x是小于10的非负数”,用MATLAB表达式可写为
  17. 华为社招技术二面,总结复盘
  18. 积小胜为大胜 投资大师教你三种有效的投资方法
  19. (数电实验报告)用Verilog–HDL语言设计一个8线3线优先编码器
  20. 设计模式----装饰模式

热门文章

  1. 智能工厂的IGT数据采集网关-PLC与数据库双向通讯的多种SQL语句配置
  2. 个人小程序支持哪些小程序服务类目
  3. 模拟波束成形和数字波束成形的区别
  4. POJ-2528 Mayor's posters (离散化, 线段树)
  5. el-upload 模拟点击
  6. STM32F103C8T6引脚功能图
  7. 性能测试平台搭建及简单使用(jmeter分布式+influxdb2.0+grafana)附性能测试报告
  8. G1D33-BTG复现重跑实验
  9. 章鱼猫(Octocat)
  10. 【0-1背包】二进制灰狼算法解决0-1背包问题【Matlab】