实现一个网易云音乐的 BottomSheetDialog
作者:林冠宏 / 指尖下的幽灵
GitHub : https://github.com/af913337456/
腾讯云专栏: https://cloud.tencent.com/developer/user/1148436/activities
目录
- 前序
- 直观对比下 gif 效果
- Android SDK 自带的
BottomSheetDialog - 网易云音乐 的
BottomSheetDialog - 我开源 的仿网易云音乐
BottomSheetDialog
- Android SDK 自带的
- 核心代码简述
前序:
因为
APP需要参照到网易云音乐的 BottomSheetDialog的效果,找了一圈没找到,所以动手写了一个,涉及圈子里经常露面的知识点有下面三点,也是个实战应用
- 事件分发系列的--冲突处理 & 分发顺序
- View 绘制流程的--Measure 模式
- 相对屏幕取 View 的坐标
先来直观对比下 gif 效果
- 首先是-- Android SDK 自带的
BottomSheetDialog - 然后是--网易云音乐 的
BottomSheetDialog - 最后是--我开源 的仿网易云音乐
BottomSheetDialog
首先是-- Android SDK 自带的 BottomSheetDialog
下面的 gif 图是一个Android SDK 自带的 BottomSheetDialog 内部加了 RecyclerView 列表控件的效果
可以看出:
- 下滑动作会收起,隐藏掉
dialog - 上滑会完全展开
- 展开后,才能滑动
RecyclerView内部
其次
- 如果你内部使用的是
ListView列表控件,你会发现会有其他奇怪的情况。
然后是--网易云音乐 的 BottomSheetDialog
下面的 gif 图是一个Android 版 网易云音乐的BottomSheetDialog效果
可以看出:
- 下滑动作会有
范围回弹,也就是下滑到一定距离才会收起,隐藏掉dialog - 上滑不给展开
- 能够在半展开的情况下,内嵌滑动列表控件,例如
listView - 和列表控件滑动不冲突,在
列表控件滑尽的时候,可以下滑隐藏dialog
最后是--我开源 的仿网易云音乐 BottomSheetDialog
可以看出,效果和网易云的一样
核心代码简述
SDK 的 BottomSheetDialog 内部布局的结构如下:
--FrameLayout
--|--CoordinatorLayout
--|--|--FrameLayout
--|--|--|--Our ContentView // 最后是我们设置的 ContentView
CoordinatorLayout 在 Action_Move 事件时,必要的时候对其子 View 进行事件拦截,所以有第一个 gif 看到的效果,具体不详说。
第一个步骤 --- 防止 CoordinatorLayout 对 Our ContentView 拦截事件
这里使用 ListView 做例子,设置onTouch,在内部做适当时候的适当阻止CoordinatorLayout 拦截事件。
// ListView
setOnTouchListener(
new OnTouchListener() {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
if (bottomCoordinator == null)
return false;
// 拿出当前列表第一个可见 item 的 pos
int firstVisiblePos = getFirstVisiblePosition();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downY = event.getRawY();
bottomCoordinator.requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
moveY = event.getRawY();
if ((moveY - downY) > 10) {
// 下滑情况
if (firstVisiblePos == 0 && isOverScroll) {
// 列表控件,例如 listView 已经滑到头了,允许被拦截
bottomCoordinator.requestDisallowInterceptTouchEvent(false);
break;
}
}
// 上滑时,总是不允许被拦截,listView 消耗当前事件
bottomCoordinator.requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
break;
}
return false;
}
}
);
第二个步骤,让 ListView 能在半展开的情况下,显示完整的数据条数
重写 onMeasure,使用自定义的测量模式。
// ListView
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if(bottomCoordinator == null){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
// 以黄金分割的尺寸来显示 listView 的高度
int size = (int)((float)(getResources().getDisplayMetrics().heightPixels*0.618));
int newHeightSpec = MeasureSpec.makeMeasureSpec(
size,
// mode,非法的情况,super 直接使用 size 做高,看源码后,你会发现也可以使用 exact 模式
Integer.MIN_VALUE
);
super.onMeasure(widthMeasureSpec, newHeightSpec);
}
第三个步骤,实现 BottomSheetDialog 范围回弹
/**
* 添加 top 距离顶部多少的时候触发收缩效果
* @param targetLimitH int 高度限制
*/
@SuppressWarnings("all")
public void addSpringBackDisLimit(final int targetLimitH){
if(coordinator == null)
return;
// totalHeight 屏幕的总像素高度
final int totalHeight = getContext().getResources().getDisplayMetrics().heightPixels;
// currentH 当前我们的 列表控件 展开的高度
final int currentH = (int) ((float)totalHeight*0.618); // 0.618 是黄金分割点,随便自定义,对应 contentView
final int leftH = totalHeight - currentH;
coordinator.setOnTouchListener(
new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_MOVE:
// 计算相对于屏幕的 坐标
bottomSheet.getGlobalVisibleRect(r);
break;
case MotionEvent.ACTION_UP:
// 抬手的时候判断
int limitH;
if(targetLimitH < 0)
limitH = (leftH + currentH/3);
else
limitH = targetLimitH;
if(r.top <= limitH)
if (mBehavior != null)
// 范围内,让它继续是 半展开的状态
mBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
break;
}
return false;
}
}
);
}
完
实现一个网易云音乐的 BottomSheetDialog的更多相关文章
- 用VUEJS做一个网易云音乐
前言:自己学习VUEJS也一段时间,但一直没有做出来一东西.我自己一直喜欢用网易云音乐app,于是乎就做了这个app. 项目截图 技术栈 vue全家桶 (vue vue-router vuex) ax ...
- NetCloud——一个网易云音乐评论抓取和分析的Python库
在17的四月份,我曾经写了一篇关于网易云音乐爬虫的文章,还写了一篇关于评论数据可视化的文章.在这大半年的时间里,有时会有一些朋友给我发私信询问一些关于代码方面的问题.所以我最近抽空干脆将原来的代码整理 ...
- 网易云音乐PC端刷曲快捷键
文章首发于szhshp的第三边境研究所(szhshp.org), 转载请注明 网易云音乐PC端刷曲快捷键 好吧我承认我特别懒 云音乐其实做的还不错,FM推荐的算法明显比虾米好. 虾米可以听的曲子都 ...
- 使用webcollector爬虫技术获取网易云音乐全部歌曲
最近在知乎上看到一个话题,说使用爬虫技术获取网易云音乐上的歌曲,甚至还包括付费的歌曲,哥瞬间心动了,这年头,好听的流行音乐或者经典老歌都开始收费了,只能听不能下载,着实很郁闷,现在机会来了,于是开始研 ...
- 用vuejs仿网易云音乐(实现听歌以及搜索功能)
前言 前端时间学了vue,一开始看了vue1.0,后来实在觉得技术总得实践,就直接上手vue2.0.然后花了将近一周时间做了一个网易云音乐的小项目.一开始觉得项目比较小,没必要用vuex所以就没有使用 ...
- WPF仿网易云音乐系列(序)
1.简介 由于之前做了一个播放器,苦于不懂界面设计,只得去借鉴借鉴一些成功的作品,网易云音乐就甚合朕心,哈哈,最后做出来的效果如下: 本系列文章就来和大家讨论以下,如何用WPF去仿制一个网易云音乐来: ...
- 使用python获取网易云音乐无损音频教程
博客园主页:http://www.cnblogs.com/handoing/ github项目:https://github.com/handoing/get-163-music 环境:Python ...
- CentOS 7.4 安装 网易云音乐
CentOS 7.4 安装 网易云音乐 本文包含: 安装dnf 编译gcc 5.4.0 安装各种包 安装网易云音乐贯穿全局; 安装环境: CentOS 7.4, kernel3.10.0, gcc4. ...
- python爬虫:了解JS加密爬取网易云音乐
python爬虫:了解JS加密爬取网易云音乐 前言 大家好,我是"持之以恒_liu",之所以起这个名字,就是希望我自己无论做什么事,只要一开始选择了,那么就要坚持到底,不管结果如何 ...
随机推荐
- 使用localtunne一分钟搞定微信公众号接入
记得15年那个刚刚进入工作的时候,公司有个微信公众号的项目,那个时候微信官方没有什么调试工具,也没有什么比较好的本地调试工具.当时有个功能需要调用微信JSSDK里面的扫一扫的功能.由于本地不能调试 ...
- 【RMAN】Oracle中如何备份控制文件?备份控制文件的方式有哪几种?
真题1. 如何备份控制文件?备份控制文件的方式有哪几种? 答案:备份控制文件的方式有多种. ① 备份控制文件可以在线进行: SQL> ALTER DATABASE BACKUP CONTROLF ...
- SpringtMVC中配置 <mvc:annotation-driven/> 与 <mvc:default-servlet-handler/> 的作用与源码解析
基于 Spring4.X 来学习 SpringtMVC, 在学习过程中,被"告知"在 XML 配置文件中建议设置如下两项: 一直不明白为什么,但又甘心.于是,花了一点时间来调试源码 ...
- java 连接 elasticsearch 报错java.lang.NoClassDefFoundError: org/apache/http/auth/Credentials 解决
您的问题是您在应用程序类路径中缺少必需的JAR(这导致ClassNotFound异常).如果您下载了包含IP Camera驱动程序(webcam-capture-driver-ipcam-0.3.10 ...
- 笔记:MyBatis 使用 Java API配置
我们已经讨论了各种MyBatis配置元素,如envronments.typeAlias和typeHandlers,以及如何使用XML配置它们.即使你想使用基于JavaAPI的MyBatis配置,MyB ...
- 巧用linux版powershell,管理linux下的docker
大家好,我把用powershell的docker马甲命令的好处,放在了页面下方,从第五章开始. powershell 传教士 原创文章 始于 2017-09-07 允许转载,但必须保留名字和出处,否则 ...
- SpringBoot 自定义Banner
在2016年的最后一天,借用Spring Boot的Banner向各位程序猿同仁们问候一声:Happy New Year. 接下来我们就来介绍一下这个轻松愉快的自定义banner功能.实现的方式非常简 ...
- 关于yaml语言
yaml语言广泛用于书写配置文件. 主要特点如下: 1.使用缩进表示层级关系,缩进使用空格键(非Tab键) 2.缩进的空格数目不要求,只要相同层级的元素左侧对其即可 3.#之后的内容为注释 4.yam ...
- 仿京东树形菜单插件hovertree
hovertree是一个仿京东的树形菜单jquery插件,暂时有银色和绿色两种. 官方网址:http://keleyi.com/jq/hovertree/欢迎下载使用 查看绿色效果:http://ke ...
- [日常] NOIP前集训日记
写点流水账放松身心... 10.8 前一天考完NHEEE的一调考试终于可以开始集训了Orz (然后上来考试就迟到5min, GG) T1维护队列瞎贪心, 过了大样例交上去一点也不稳...T出翔只拿了5 ...