[MAUI 项目实战] 手势控制音乐播放器(一): 概述与架构
这是一篇系列博文。请关注我,学习更多.NET MAUI开发知识!
- [MAUI 项目实战] 手势控制音乐播放器(一): 概述与架构
- [MAUI 项目实战] 手势控制音乐播放器(二): 手势交互
- [MAUI 项目实战] 手势控制音乐播放器(三): 动画
- [MAUI 项目实战] 手势控制音乐播放器(四):圆形进度条
在之前的博文中提到这个项目,它是为音乐播放器专门开发的基于手势控制的UI界面。
此UI界面可以让用户在不看屏幕的情况下,通过手势来控制音乐播放器的各种操作,如播放、暂停、下一首、上一首。

手势来控制的交互方式适合不方便看手机屏幕时简单的音乐播放需求,在驾车、运动等场景下有较好的用户体验。

架构
跨平台
使用.NET MAU实现跨平台支持,本项目可运行于Android、iOS平台。


播放内核
播放内核使用MatoMusic.Core,查看此博文[MAUI 项目实战] 音乐播放器(二):播放内核
此项目重点关注的是手势交互UI,播放内核的实现将不再赘述。
手势原理
在播放界面的8个方向,分别放置控制区域,通过拖拽圆形专辑(pan)到控制区域(pit),实现对应的控制操作。此示例实现了快进,快退,下一曲,上一曲,播放/暂停操作,pan和pit将在下一章节介绍。
拖拽平移和控制区域的关系,可以抽象成四个状态,分别是Out,In,Over,Start。
手势状态类型PanType定义如下:
- In:pan进入pit时触发,
- Out:pan离开pit时触发,
- Over:释放pan时触发,
- Start:pan开始拖拽时触发
public enum PanType
{
Out, In, Over, Start
}
对拖拽手势的处理,由手势容器控件PanContainer封装,实现方式将在下一章节介绍。
一次有效的控制,经过Start -> In -> Out -> Over的状态变化,并且手指释放位置是在pit的范围内。
当整个控制触发完成后,控件将触发OnfinishedChoise事件。
基本控制
在页面中订阅这个事件,在事件方法中实现控制逻辑。
如上一曲操作,订阅事件后,实现如下逻辑:
private void DefaultPanContainer_OnOnfinishedChoise(object sender, PitGrid e)
{
CurrentPitView = e;
switch (CurrentPitView.PitName)
{
case "LeftPit":
MusicRelatedViewModel.PreAction(null);
break;
...
}
}
控件会将当前触发的pit传递给事件方法,通过pit的名称,可以判断当前触发的是哪个控制区域。
控件在经过pit时会启用广播事件,使用CommunityToolkit库的 WeakReferenceMessenger实现了消息机制,订阅此事件消息可以接收到控件运动的细节,在事件方法中实现自己的逻辑,如界面元素样式的改变。
public NowPlayingPage()
{
InitializeComponent();
WeakReferenceMessenger.Default.Register<PanActionArgs, string>(this, TokenHelper.PanAction, PanActionHandler);
...
}
如在拖拽开始时,显示控制区域的提示信息,拖拽结束时,隐藏提示信息。
private async void PanActionHandler(object recipient, PanActionArgs args)
{
var parentAnimation = new Animation();
Animation scaleUpAnimation1;
Animation scaleUpAnimation2;
switch (args.PanType)
{
case PanType.Over:
scaleUpAnimation1 = new Animation(v => this.PitContentLayout.Opacity = v, PitContentLayout.Opacity, 0, Easing.CubicOut);
scaleUpAnimation2 = new Animation(v => this.TitleLayout.Opacity = v, TitleLayout.Opacity, 1, Easing.CubicOut);
parentAnimation.Add(0, 1, scaleUpAnimation1);
parentAnimation.Add(0, 1, scaleUpAnimation2);
parentAnimation.Commit(this, "RestoreAnimation", 16, 250);
...
快进/快退
拖拽停留在左右控制区域超过一定时间,将触发“快进”或“快退”
播放界面拥有一个定时器,用于拖拽快进、快退功能
private IDispatcherTimer _dispatcherTimer;
拖拽进入控制区域时,启动定时器,停留在左右控制区域大于2s时将触发定时器Tick事件,执行快进或快退操作。
private async void PanActionHandler(object recipient, PanActionArgs args)
{
switch (args.PanType)
{
...
case PanType.In:
switch (args.CurrentPit?.PitName)
{
case "LeftPit":
_dispatcherTimer =Dispatcher.CreateTimer();
_dispatcherTimer.Interval=new TimeSpan(0, 0, 2);
_dispatcherTimer.Tick+= async (o, e) =>
{
this.TipLabel.Text = FaIcons.IconFastBackward;
this.TipTextLabel.Text = "快退";
_runCount++;
await MusicRelatedViewModel.StartFastSeeking(-2);
};
_dispatcherTimer.Start();
this.TipTextLabel.Text = "上一曲";
break;
...
_runCount是个全局变量,记录是否已经执行过快进或快退操作,当退出控制区域时,如果已经执行过快进或快退操作,将停止快进或快退操作,并将计时器停止。
case PanType.Out:
this.PitTipLayout.Children.Clear();
if (this._runCount > 0)
{
MusicRelatedViewModel.EndFastSeeking();
}
if (_dispatcherTimer!=null)
{
_dispatcherTimer.Stop();
}
_runCount = 0;
this.TipTextLabel.Text = string.Empty;
break;
同理,在松手时,应该停止快进或快退操作,并将计时器停止。
case PanType.Over:
...
MusicRelatedViewModel.EndFastSeeking();
if (_dispatcherTimer!=null)
{
_dispatcherTimer.Stop();
}
_runCount = 0;
沉浸模式
_dispatcherTimer2是控制界面进入“沉浸模式”的定时器,当界面无操作5s之后界面将进入沉浸模式,隐藏标题栏。
private void SetupFullScreenMode(int delay = 5)
{
_dispatcherTimer2 =Dispatcher.CreateTimer();
_dispatcherTimer2.Interval=new TimeSpan(0, 0, delay);
_dispatcherTimer2.Tick+= (o, e) =>
{
this.MainCircleSlider.BorderWidth = 3;
this.TitleLayout.FadeTo(0);
};
_dispatcherTimer2.Start();
}
有操作进行时,恢复到正常模式。
case PanType.Start:
...
if (_dispatcherTimer2.IsRunning)
{
_dispatcherTimer2.Stop();
}
SetupNormalMode();
break;
下一章将逐步展开手势控制的实现细节。
项目地址
[MAUI 项目实战] 手势控制音乐播放器(一): 概述与架构的更多相关文章
- 团队项目 NABCD分析java音乐播放器
NABCD分析java音乐播放器 程设计题目:java音乐播放器 一.课程设计目的 1.编程设计音乐播放软件,使之实现音乐播放的功能. 2.培养学生用程序解决实际问题的能力和兴趣. 3.加深java中 ...
- Android开发实战之简单音乐播放器
最近开始学习音频相关.所以,很想自己做一个音乐播放器,于是,花了一天学习,将播放器的基本功能实现了出来.我觉得学习知识点还是蛮多的,所以写篇博客总结一下关于一个音乐播放器实现的逻辑.希望这篇博文对你的 ...
- Android(java)学习笔记234: 服务(service)之音乐播放器
1.我们播放音乐,希望在后台长期运行,不希望因为内存不足等等原因,从而导致被gc回收,音乐播放终止,所以我们这里使用服务Service创建一个音乐播放器. 2.创建一个音乐播放器项目(使用服务) (1 ...
- Android(java)学习笔记177: 服务(service)之音乐播放器
1.我们播放音乐,希望在后台长期运行,不希望因为内存不足等等原因,从而导致被gc回收,音乐播放终止,所以我们这里使用服务Service创建一个音乐播放器. 2.创建一个音乐播放器项目(使用服务) (1 ...
- Andriod小项目——在线音乐播放器
转载自: http://blog.csdn.net/sunkes/article/details/51189189 Andriod小项目——在线音乐播放器 Android在线音乐播放器 从大一开始就已 ...
- Swift实战-豆瓣电台(九)简单手势控制暂停播放(全文完)
Swift实战-豆瓣电台(九)简单手势控制暂停播放 全屏清晰观看地址:http://www.tudou.com/programs/view/tANnovvxR8U/ 这节我们主要讲UITapGestu ...
- Android应用--简、美音乐播放器增加音量控制
Android应用--简.美音乐播放器增加音量控制 2013年6月26日简.美音乐播放器继续完善中.. 题外话:上一篇博客是在6月11号发的,那篇博客似乎有点问题,可能是因为代码结构有点乱的原因,很难 ...
- 自定义css样式结合js控制audio做音乐播放器
最近工作需求需要播放预览一些音乐资源,所以自己写了个控制audio的音乐播放器. 实现的原理主要是通过js调整audio的对象属性及对象方法来进行控制: 1.通过play().pause()来控制音乐 ...
- HTML5项目笔记4:使用Audio API设计绚丽的HTML5音乐播放器
HTML5 有两个很炫的元素,就是Audio和 Video,可以用他们在页面上创建音频播放器和视频播放器,制作一些效果很不错的应用. 无论是视屏还是音频,都是一个容器文件,包含了一些音频轨道,视频轨道 ...
- swift 音乐播放器项目-《lxy的杰伦情歌》开发实战演练
近期准备将项目转化为OC与swift混合开发.试着写一个swift音乐播放器的demo,体会到了swift相对OC的优势所在.废话不多说.先上效果图: watermark/2/text/aHR0cDo ...
随机推荐
- 【转载】Python 在已存在的excel表格中写入数据
由于每天都要汇总日报数据,其实就是个复制粘贴的工作,将多个表的数据汇总成一个表格,工作较枯燥,于是想到用Python帮我完成这个简单又粗糙的工作.写一下我学到的几个小技巧,下次忘记怎么使用的时候,还能 ...
- 5vue 样式绑定
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- django_模板层的过滤器和继承
**************************************************************************************************** ...
- windows 2016 安装docker
windows 2016 安装docker 前提条件:windows server 2016安装更新 1:用管理员打开windows PowerShell Install-PackageProvide ...
- JAVA 学习打卡 day3
2022-04-25 22:53:16 1.运算符 表达式是由操作数与运算符所组成Java中的语句有很多种形式,表达式就是其中一种形式.表达式是由操作数与运算符所组成,操作数可以是常量.变量也可以是方 ...
- What is RSS
What is RSS?RSS (Rich Site Summary) is a format for delivering regularly changing web content. Many ...
- FIR滤波器的设计
FIR数字滤波器的设计 线性相位FIR滤波器的特点 单位冲激响应:\(h(n),0\leq n\leq N-1\) 系统函数:\(H(z)=\sum_{n=0}^{N-1}h(n)z^{-n}\) 零 ...
- 纯js实现字符串formate方法
function format(pattern){ if(! (pattern instanceof String)){ throw new TypeError("错误的参数类型" ...
- js/css实现图片轮播
实现样式: tplb.css ul, li { padding: 0; margin: 0; list-style: none; } .adver { margin: 0 auto; width: 7 ...
- 使用Navicat查询后 , 在结果处更改数据
参考资料: https://blog.csdn.net/weixin_43786801/article/details/125364995 问题: 在使用Navicat查询是,往往想直接对查询结果进行 ...