Android仿网易云音乐歌单详情页
效果图

实现思路:
1、Activity设置自定义Shared Element切换动画
2、透明状态栏(透明Toolbar,使背景图上移)
3、Toolbar底部增加和背景一样的高斯模糊图,并上移图片(为了使背景图的底部作为Toolbar的背景)
4、上下滑动,通过NestedScrollView拿到移动的高度,同时调整Toolbar的背景图透明度
1、Activity设置自定义元素共享切换动画
大家可以发现页面跳转时图片移动的是一个曲线路径,我们可以定制View的过渡切换效果,这是Material Design中比较常见的用法,Api21以上才有效。需要在开启页面时使用:
ActivityOptions.makeSceneTransitionAnimation()
其中定义共享的view和transitionName。然后在对应的Activity里创建ArcMotion对象。ArcMotion是PathMotion子类,是个曲线路径,对应代码片:
// Activity设置自定义 Shared Element切换动画if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//定义ArcMotionArcMotion arcMotion = new ArcMotion();arcMotion.setMinimumHorizontalAngle(50f);arcMotion.setMinimumVerticalAngle(50f);//插值器,控制速度Interpolator interpolator = AnimationUtils.loadInterpolator(this, android.R.interpolator.fast_out_slow_in);//实例化自定义的ChangeBoundsCustomChangeBounds changeBounds = new CustomChangeBounds();changeBounds.setPathMotion(arcMotion);changeBounds.setInterpolator(interpolator);changeBounds.addTarget(binding.include.ivOnePhoto);//将切换动画应用到当前的Activity的进入和返回getWindow().setSharedElementEnterTransition(changeBounds);getWindow().setSharedElementReturnTransition(changeBounds);}// 开启
Intent intent = new Intent(context, MovieDetailActivity.class);
intent.putExtra("bean", positionData);
ActivityOptionsCompat options =ActivityOptionsCompat.makeSceneTransitionAnimation(context,imageView, CommonUtils.getString(R.string.transition_book_img));//与xml文件对应ActivityCompat.startActivity(context, intent, options.toBundle());
值得注意的是:因为加载图片要一点时间,切换页面时就会出现闪烁的情况,而如果取的是缓存就不会有这样的问题,所以这里有个小技巧,就是起初Glide加载的图片就指定固定的大小(.override(120,120)),这样图片就会被缓存起来,等到跳转时就取缓存。具体还请大家看项目源码。
2、透明状态栏
// 为头部是View的界面设置状态栏透明
StatusBarUtil.setTranslucentImageHeader(this, 0, binding.titleToolBar);
其中内容根布局不要设置android:fitsSystemWindows="true",这样会额外添加一个状态栏。其中StatusBarUtil,是一个为Android App 设置状态栏的工具类。
3、Toolbar的背景图
仔细分析后发现网易云音乐的Toolbar的背景其实显示的是高斯模糊图的底部,所以这里基本套路是Toolbar是透明的,后面背景图取的是高斯模糊图的底部一部分。

调整Toolbar背景图位置
// Toolbar的高度
int toolbarHeight = binding.titleToolBar.getLayoutParams().height;
// Toolbar+状态栏的高度
final int headerBgHeight = toolbarHeight + StatusBarUtil.getStatusBarHeight(this);// 使背景图向上移动到图片的最底端,保留Toolbar+状态栏的高度
binding.ivTitleHeadBg.setVisibility(View.VISIBLE);
ViewGroup.LayoutParams params = binding.ivTitleHeadBg.getLayoutParams();
ViewGroup.MarginLayoutParams ivTitleHeadBgParams = (ViewGroup.MarginLayoutParams) binding.ivTitleHeadBg.getLayoutParams();
int marginTop = params.height - headerBgHeight;
ivTitleHeadBgParams.setMargins(0, -marginTop, 0, 0);
binding.ivTitleHeadBg.setImageAlpha(0);
显示Toolbar背景图
监听图片显示,在显示之后将其设置为透明色,然后在滑动的时候渐变。这里值得注意的是在设置图片时不要设置加载中的图片,不然初始化时达不到透明的效果。
// 高斯模糊背景,加载后将背景设为透明
Glide.with(this).load(NeteasePlaylistActivity.IMAGE_URL_MEDIUM)//.placeholder(R.drawable.stackblur_default).error(R.drawable.stackblur_default).bitmapTransform(new BlurTransformation(this, 14, 3))// 设置高斯模糊.listener(new RequestListener<String, GlideDrawable>() {//监听加载状态@Overridepublic boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {return false;}@Overridepublic boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {// Toolbar背景设为透明binding.titleToolBar.setBackgroundColor(Color.TRANSPARENT);// 背景图初始化为全透明binding.ivTitleHeadBg.setImageAlpha(0);binding.ivTitleHeadBg.setVisibility(View.VISIBLE);return false;}
}).into(binding.ivTitleHeadBg);
其中引入的库应为如下,将官方Glide的额外扩展了,使其可以支持高斯模糊。
compile 'jp.wasabeef:glide-transformations:2.0.1'
4、上下滑动,渐变背景图透明度
由于NestedScrollView滚动监听只能在API23以上才能使用,这里为了兼容需要额外处理,定义滚动接口,具体:MyNestedScrollView
/*** 根据页面滑动距离改变Header透明度方法*/private void scrollChangeHeader(int scrolledY) {if (scrolledY < 0) {scrolledY = 0;}float alpha = Math.abs(scrolledY) * 1.0f / (slidingDistance);Drawable drawable = binding.ivTitleHeadBg.getDrawable();if (drawable != null) {if (scrolledY <= slidingDistance) {// title部分的渐变drawable.mutate().setAlpha((int) (alpha * 255));binding.ivTitleHeadBg.setImageDrawable(drawable);} else {drawable.mutate().setAlpha(255);binding.ivTitleHeadBg.setImageDrawable(drawable);}}}
这样基本的效果就实现啦,其中如有需要还可以做些额外的处理,如当背景图不透明时切换标题等~
实践了很多实现这个页面的方法,目前为止这个方案是最好的,效果体验几乎是一样,其中涉及到的知识点有:1、页面跳转共享元素曲线动画;2、透明状态栏;3、Glide监听图片加载状态和加载固定大小图片等;4、NestedScrollView在Api23下的滑动兼容。
源码地址
https://github.com/youlookwhat/NeteaseMusicUI
相关文章:

Android仿网易云音乐歌单详情页
效果图实现思路:1、Activity设置自定义Shared Element切换动画2、透明状态栏(透明Toolbar,使背景图上移)3、Toolbar底部增加和背景一样的高斯模糊图,并上移图片(为了使背景图的底部作为Toolbar的背景)4、上…...

linux基本功系列之free命令实战
文章目录前言一. free命令介绍二. 语法格式及常用选项三. 参考案例3.1 查看free相关的信息3.2 以MB的形式显示内存的使用情况3.3 以总和的形式显示内存的使用情况3.4 周期性的查询内存的使用情况3.5 以更人性化的形式来查看内存的结果输出总结前言 大家好,又见面了…...

华为OD机试模拟题 用 C++ 实现 - 连续子串(2023.Q1)
最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 最多获得的短信条数(2023.Q1)) 文章目录 最近更新的博客使用说明连续子串题目输入输出示例一输入输出说明Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD …...

【软考——系统架构师】UML 建模与架构文档化
🔎这里是【软考——系统架构师】,关注我考试轻松过线 👍如果对你有帮助,给博主一个免费的点赞以示鼓励 欢迎各位🔎点赞👍评论收藏⭐️ 文章目录UML 基础UML 软件开发过程系统架构文档化送书福利UML 基础 U…...
Spring中常用注解
声明 bean 的注解 Component:泛指各种组件 Controller、Service、Repository 都可以称为Component Controller:控制层 Service:业务层 Repository:数据访问层Bean 的生命周期属性 Scope 设置类型包括:设置 Spring 容器…...

基于SpringCloud的可靠消息最终一致性06:轮询事务消息
上一节把可靠消息最终一致性的正常逻辑代码顺序执行了一次,并且对于同一个事务消息,在正常情况下它要被发送至少两次。 这是因为在发送消息之前,TransactionMessageService就已经把消息保存到了数据库中。而在首次消费完消息后,TransactionMessageListener并没有从数据库中…...

Python Flask + Echarts 轻松制作动态酷炫大屏( 附代码)
目录一、确定需求方案二、整体架构设计三、编码实现 (关键代码)四、完整代码五、运行效果1.动态实时更新数据效果图 说明: 其中 今日抓拍,抓拍总数,预警信息统计,监控点位统计图表 做了动态实时更新处理。 2.静态…...
Wepack(1):SourceMap讲解以及使用
今天我们来讲讲定位源码的工具 Sourcemap , 我们先讲最简单的配置,之后才补充 sourcemap 的其他属性 Sourcemap 作用 可以在打包的代码直接对应相应源码 例如 vue2 , vue3可以把对应的错误上传到相关服务器 使用 webpack.config.js const config …...

华为OD机试题,用 Java 解【最多等和不相交连续子序列】问题
最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…...

Kubernetes06:Controller
Kubernetes06:Controller 1、什么是controller 管理和运行容器的对象,是一个物理概念 在集群上管理和运行容器的对象 2、Pod和Controller之间的关系 Pod是通过controller来实现应用的运维 比如伸缩、滚动升级等等操作Pod和Controller之间通过 label 标签建立关系…...
采购文件中 RFI、RFQ、RFP、IFB的区别
【PMBOK的描述】 采购文件用于征求潜在卖方的建议书。如果主要依据价格来选择卖方(如购买商业或标准产品时),通常就使用标书、投标或报价等术语。如果主要依据其他考虑(如技术能力或技术方法)来选择卖方࿰…...

linux升级gcc版本详细教程
0.前言一般linux操作系统默认的gcc版本都比较低,例如centos7系统默认的gcc版本为4.8.5。gcc是从4.7版本开始支持C11的,4.8版本对C11新特性的编译支持还不够完善,因此如果需要更好的体验C11以及以上版本的新特性,需要升级gcc到一个…...

NBA Top Shot 跌落神坛
近日,美国职业篮球联盟(NBA)授权的NFT 项目“NBA Top Shot Moments”被纽约法院初步裁定为“可能符合证券的定义”,虽然这不是对2021年用户指控该项目违法的最终判决,但这个裁定引发了市场担忧,部分NFT的地…...
状态管理Pinia使用详解(带你入门)
状态管理Pinia使用详解(带你从入门到入神) 序: 如果你之前使用过 vuex 进行状态管理的话,那么 pinia 就是一个类似的插件。它是最新一代的轻量级状态管理插件。你可以通过defineStore来简单创建一个存储管理。 与 vuex 相比,pinia 提…...

Linux系统基础命令(一)
一、图形界面和终端界面 图形界面:是指采用图形方式显示的计算机操作用户界面。 终端界面:是指黑底白字的命令行界面。 什么是tty呢? tty:终端设备的统称。 tty一词源于Teletypes,或者teletypewriters,…...

djvu批量转换为pdf的工具和djvu阅读器(附下载链接)
简介 DjVuToy是一款美观易用、功能强大的DjVu处理工具,DjVuToy官方版功能包括图像文件转DjVu,支持PDG、BMP、GIF等格式。转换的同时可以进行OCR,生成双层DjVu。可以插入、删除、移动、旋转多页DjVu中的页面。还可以将多个DjVu文件合并成一个&…...

Linux | 分布式版本控制工具Git【版本管理 + 远程仓库克隆】
文章目录一、前言二、有关git的相关历史介绍三、Git版本管理1、感性理解 —— 大学生实验报告2、程序员与产品经理3、张三的CEO之路 —— 版本管理工具的诞生四、如何在Linux上使用Git1、创建仓库2、将仓库克隆到本地3、git三板斧① git add② git commit③ git push4、有关git…...

FFmpeg 编译和集成
背景FFmpeg 是一款知名的开源音视频处理软件,它提供了丰富而友好的接口支持开发者进行二次开发。FFmpeg 读作 “ef ef em peg” ,其中的 “FF” 指的是 “Fast Forward”,“mpeg” 则是 “Moving Picture Experts Group” (动态图…...

OOM的俩种情况---主动kill/被动kill
出现OOM, 有两种处理方式:1. 主动Kill; 2. 被动Kill 例:HBase Region Server OOM定位问题复盘 现象 在HBase资源隔离项目中,对测试集群进行压测时,发现region server会出现崩溃的情况,单机请求量从>200到~50每秒都…...
ssh远程连接ECS实例连接失败
尝试通过 SSH 远程连接服务来连接ECS云服务器实例时,收到“连接被拒”或“连接超时”的错误信息,可能的原因分析如下: 错误信息描述 1、错误消息:“ssh: connect to ecs-X-X-X-X.compute-xxxxxxxxx.com port 22: Connection tim…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...

Python训练营-Day26-函数专题1:函数定义与参数
题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...