Flutter仿网易云音乐:播放界面
写在前头
本来是要做一个仿网易云音乐的flutter项目,但是因为最近事情比较多,项目周期跨度会比较长,因此分几个步骤来完成。这是仿网易云音乐项目系列文章的第一篇。没有完全照搬网易云音乐的UI,借鉴了其中的黑胶唱机动画。
先贴上项目地址 github.com/KinsomyJS/f…
初步效果图
思路
这个界面实现起来其实是比较简单的,大致分为如下几个部分:
- 1.背景的高斯模糊效果
- 2.黑胶唱头的旋转动画
- 3.黑胶唱片的旋转动画
- 4.下部控制器和进度条部分
我们一个个来说实现过程。
实践
整个界面是一个堆叠视图,最下面是一个背景图片,上面覆盖一层高斯模糊半透明遮罩,再上层是title,黑胶唱机和控制器。
1. 背景高斯模糊
首先使用stack组件用来包裹堆叠视图,在里面有两个container,第一个是背景网络图片,第二个就是一个BackdropFilter。
Stack(
children: <Widget>[
new Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new NetworkImage(coverArt),
fit: BoxFit.cover,
colorFilter: new ColorFilter.mode(
Colors.black54,
BlendMode.overlay,
),
),
),
),
new Container(
child: new BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
child: Opacity(
opacity: 0.6,
child: new Container(
decoration: new BoxDecoration(
color: Colors.grey.shade900,
),
),
),
)),
...
]
复制代码
这里的高斯模糊sigmaX和sigmaY的值选择了10,然后透明度为0.6,颜色为grey.shade900。
2.黑胶唱头的旋转动画
关于动画的知识这里就不做详细介绍了,可以参考官方文档传送门
自定义动画组件在needle_anim.dart文件里。
这里将动画和组件解耦,分别定义了动画过程类PivotTransition,顾名思义围绕一个支点旋转,继承自AnimatedWidget。
支点定在child组件的topcenter位置。
注意turns不能为空,需要根据turns的值计算旋转绕过的周长,围绕Z轴旋转。
class PivotTransition extends AnimatedWidget {
/// 创建旋转变换
/// turns不能为空.
PivotTransition({
Key key,
this.alignment: FractionalOffset.topCenter,
@required Animation<double> turns,
this.child,
}) : super(key: key, listenable: turns);
/// The animation that controls the rotation of the child.
/// If the current value of the turns animation is v, the child will be
/// rotated v * 2 * pi radians before being painted.
Animation<double> get turns => listenable;
/// The pivot point to rotate around.
final FractionalOffset alignment;
/// The widget below this widget in the tree.
final Widget child;
@override
Widget build(BuildContext context) {
final double turnsValue = turns.value;
final Matrix4 transform = new Matrix4.rotationZ(turnsValue * pi * 2.0);
return new Transform(
transform: transform,
alignment: alignment,
child: child,
);
}
}
复制代码
接下来就是自定义黑胶唱头组件。
final _rotateTween = new Tween<double>(begin: -0.15, end: 0.0);
new Container(
child: new PivotTransition(
turns: _rotateTween.animate(controller_needle),
alignment: FractionalOffset.topLeft,
child: new Container(
width: 100.0,
child: new Image.asset("images/play_needle.png"),
),
),
),
复制代码
将png图片包裹在container内作为child参数传递给PivotTransition。
外部使用的时候传入一个Tween,起始位置为-0.15 ~ 0.0。
3.黑胶唱片的旋转动画
这部分代码在record_anim.dart文件内。使用了package:flutter/animation.dart提供的RotationTransition做旋转,很简单。
class RotateRecord extends AnimatedWidget {
RotateRecord({Key key, Animation<double> animation})
: super(key: key, listenable: animation);
Widget build(BuildContext context) {
final Animation<double> animation = listenable;
return new Container(
margin: new EdgeInsets.symmetric(vertical: 10.0),
height: 250.0,
width: 250.0,
child: new RotationTransition(
turns: animation,
child: new Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: NetworkImage(
"https://images-na.ssl-images-amazon.com/images/I/51inO4DBH0L._SS500.jpg"),
),
),
)),
);
}
}
复制代码
接着自定义旋转动画的控制逻辑。旋转一圈用时十五秒钟,速度为线性匀速,同时会重复旋转动画。
controller_record = new AnimationController(
duration: const Duration(milliseconds: 15000), vsync: this);
animation_record =
new CurvedAnimation(parent: controller_record, curve: Curves.linear);
animation_record.addStatusListener((status) {
if (status == AnimationStatus.completed) {
controller_record.repeat();
} else if (status == AnimationStatus.dismissed) {
controller_record.forward();
}
});
复制代码
4.下部控制器和进度条部分
播放流媒体音频使用了三方组件audioplayers,具体代码在player_page.dart文件内,封装了一个player组件,接受了一系列参数包括音频路径,播放操作回调等。该组件支持本地资源和网络资源,这里用网络音频资源做demo。
const Player(
{@required this.audioUrl,
@required this.onCompleted,
@required this.onError,
@required this.onNext,
@required this.onPrevious,
this.key,
this.volume: 1.0,
this.onPlaying,
this.color: Colors.white,
this.isLocal: false});
复制代码
在initState方法里初始化AudioPlayer对象。".."是dart的级联操作符。
audioPlayer = new AudioPlayer();
audioPlayer
..completionHandler = widget.onCompleted
..errorHandler = widget.onError
..durationHandler = ((duration) {
setState(() {
this.duration = duration;
if (position != null) {
this.sliderValue = (position.inSeconds / duration.inSeconds);
}
});
})
..positionHandler = ((position) {
setState(() {
this.position = position;
if (duration != null) {
this.sliderValue = (position.inSeconds / duration.inSeconds);
}
});
});
复制代码
开始播放代码
audioPlayer.play(
widget.audioUrl,
isLocal: widget.isLocal,
volume: widget.volume,
);
复制代码
开始播放后,durationHandler会回调音频总时长,positionHandler会回调播放进度,两个回调都返回一个Duration对象。根据这两个duration对象可以计算机播放进度的百分比,这里使用Slider组件做进度条。
new Slider(
onChanged: (newValue) {
if (duration != null) {
int seconds = (duration.inSeconds * newValue).round();
print("audioPlayer.seek: $seconds");
audioPlayer.seek(new Duration(seconds: seconds));
}
},
value: sliderValue ?? 0.0,
activeColor: widget.color,
),
复制代码
总结
整体实现是非常简单的,只要对flutter的组件有所了解就能很快写出来,后面还会加入歌词滚动功能来丰富界面。
具体项目可以到 github.com/KinsomyJS/f… 查看,也欢迎star持续关注。
参考资料
Flutter仿网易云音乐:播放界面的更多相关文章
- 2.Android高仿网易云音乐-引导界面和广告界面实现
效果图 效果图依次为图片广告,视频广告,引导界面. 系列文章目录导航 目录 1.实现分析 广告界面就是显示图片和视频,所以可以放一个图片控件,视频控件,然后跳过按钮,提示按钮,WiFi预加载提示都是放 ...
- Android高仿网易云音乐-启动界面实现和动态权限处理
效果 实现分析 基本上没有什么难点,就是布局,然后显示用户协议对话框,动态处理权限,判断是否显示引导界面,是否显示广告界面等. 布局 <?xml version="1.0" ...
- 《云阅》一个仿网易云音乐UI,使用Gank.Io及豆瓣Api开发的开源项目
CloudReader 一款基于网易云音乐UI,使用GankIo及豆瓣api开发的符合Google Material Desgin阅读类的开源项目.项目采取的是Retrofit + RxJava + ...
- C# WPF 低仿网易云音乐(PC)歌词控件
原文:C# WPF 低仿网易云音乐(PC)歌词控件 提醒:本篇博客记录了修改的过程,废话比较多,需要项目源码和看演示效果的直接拉到文章最底部~ 网易云音乐获取歌词的api地址 http://music ...
- C# WPF 低仿网易云音乐(PC)Banner动画控件
原文:C# WPF 低仿网易云音乐(PC)Banner动画控件 由于技术有限没能做到一模一样的动画,只是粗略地做了一下.动画有点生硬,还有就是没做出网易云音乐的立体感.代码非常简单粗暴,而且我也写有很 ...
- iOS 开发仿网易云音乐歌词海报
使用网易云音乐也是一个巧合,我之前一直使用QQ音乐听歌,前几天下 app 手机内存告急.于是就把QQ音乐给卸载掉了,正好晚上朋友圈里有一个朋友用网易云音乐分享了一首歌曲,于是我也就尝试下载了网易云音乐 ...
- 新鲜出炉高仿网易云音乐 APP
我的引语 晚上好,我是吴小龙同学,我的公众号「一分钟GitHub」会推荐 GitHub 上好玩的项目,一分钟 get 一个优秀的开源项目,挖掘开源的价值,欢迎关注我. 项目中成长是最快的,如何成长,就 ...
- android仿网易云音乐引导页、仿书旗小说Flutter版、ViewPager切换、爆炸菜单、风扇叶片效果等源码
Android精选源码 复现网易云音乐引导页效果 高仿书旗小说 Flutter版,支持iOS.Android Android Srt和Ass字幕解析器 Material Design ViewPage ...
- WPF仿网易云音乐系列(序)
1.简介 由于之前做了一个播放器,苦于不懂界面设计,只得去借鉴借鉴一些成功的作品,网易云音乐就甚合朕心,哈哈,最后做出来的效果如下: 本系列文章就来和大家讨论以下,如何用WPF去仿制一个网易云音乐来: ...
随机推荐
- VS2019中QT连接及使用
23:27:43 2019-08-09 qt连接VS 连接前提是在下载qt的时候将 MSVC 2017装上 点击扩展 选择管理扩展 搜索qt 选择下载 之后下载结束并重新打开后 会弹出一个 QT o ...
- 分享一下,PHP实现第四方QQ微信扫码登陆,不接入qq互联以及微信开发者平台就可以实现用户对接鹅厂,phpQQ微信扫码登陆
自己抓的QQ包以及整合了网上一些已经封装好了的代码具体如下:QQ: <?php class QQ extends Curl_Api { //获取登录验证码 public function QRc ...
- 在scratch中怎样编写抓蝴蝶游戏
打开scratch2.0软件,进入工作界面,将语言切换为简体中文:将默认的演员猫删除掉:在新建背景中选择“从背景库中选择背景”: 选择户外,来点一个背景图flower bed,然源后点下面的确定: 背 ...
- sqlchemy查询的其他操作
sqlalchemy的数据查询排序 1 .正序排序:session.query(model).order_by(model.attr).all() session.query(model).order ...
- Python 1基础语法四(数字类型、输入输出汇总和命令行参数)
一.数字(Number)类型 python中数字有四种类型:整数.布尔型.浮点数和复数. int (整数), 如 1, 只有一种整数类型 int,表示为长整型,没有 python2 中的 Long. ...
- shell脚本编程(ubantu)
项目 内容 这个作业属于那个课程 这里是链接 作业要求在哪里 这里是链接 学号-姓名 17041506-张政 作业学习目标 了解shell脚本的概念及使用:掌握shell脚本语言的基本语法:学习简单的 ...
- python3(二十一) pip
先确保安装了windows的Python的pip 出现上图说明安装了,命令未找到则没有安装 安装一个图形处理的第三方库 Anaconda安装第三方库 我们经常需要用到很多第三方库,如MySQL驱动程序 ...
- tf.nn.bias_add 激活函数
tf.nn.bias_add(value,bias,data_format=None,name=None) 参数: value:一个Tensor,类型为float,double,int64,int32 ...
- for循环in遍历
<script> //对象本身没有length,所以不能用for循环遍历 //要用for...in...循环 var aaa = {"name":"拴住&qu ...
- Connections in Galaxy War ZOJ - 3261 (并查集)
点权并查集的反向离线操作 题目大意:有n个stars,每一个都一定的“颜值”.然后stars与stars之间可以相连,query c表示再与c相连的stars中,颜值比c高的,stars的标号,如果有 ...