Flutter 开发的极简风格音乐播放器

  • 去年失业闲的无聊开发了一个简单的音乐播放器,过去一年,个人水平也有长进,近期花时间使用最新版Flutter SDK 重构。

  • 其实是有设计图的进行参考的,具体的作者已经找不到了,不过贴一下展示一下。

  • Flutter 在不同设备上的UI兼容性非常好。

项目中一些技术分享

半透明的高斯模糊AppBar 和 BottomNavigationBar

# Flutter 透明模糊化AppBar 和 BottomNavigationBar 优化方案

参考代码

dart 复制代码
appBar: AppBar(
    title: const Text("DM's Blur Gallery"),
    flexibleSpace: BlurWidget(child: SizedBox.expand()),
),
extendBody: true,
bottomNavigationBar: BlurWidget(
child: _buildMenus(themeData),
),

滚动列表中的高斯模糊锯齿和效果丢失问题

每个音乐卡片都存在高斯模糊区域。如果裁剪设置不合理,就会存在问题

dart 复制代码
ClipRRect(
      borderRadius: BorderRadius.circular(10),
      clipBehavior: Clip.antiAliasWithSaveLayer,

Flutter 的ClipRRect组件有四种模式,默认是hardEdge,性能较好,但是在physics: ClampingScrollPhysics() 时,滚动列表会丢失模糊效果。 Flutter 在安卓上,listview 类型 默认都是 ClampingScrollPhysics。 将Clip模式设置为Clip.antiAliasWithSaveLayer ,即可取得最佳效果。

下面是裁剪模式的粗略翻译。

dart 复制代码
none 不裁减
hardEdge 粗略裁剪
antiAlias 高精度裁剪
antiAliasWithSaveLayer 超高精度裁剪,并隔离区域

主题色切换

在main.dart的App配置中,设置

dart 复制代码
return GetMaterialApp(
      title: 'DMusic',
      theme: _getLightTheme(),
      darkTheme: _getDarkTheme(),
      themeMode: ThemeMode.dark,
      debugShowCheckedModeBanner: false,
      home: SplashPage(),
    );
dart 复制代码
colorScheme: const ColorScheme.dark(
        brightness: Brightness.dark,
        // 主色调
        primary: Colors.black,
        //主色调 - 反转
        inversePrimary: Colors.black,
        // 文字颜色
        onSurface: Colors.white,
        // 文字颜色 - 反转
        onInverseSurface: Colors.black,
        // 表面颜色
        surface: Colors.black,
        // 表面颜色 - 反转
        inverseSurface: Colors.white,
      ),

弧形进度条(支持点击和拖拽)

# Flutter 椭圆弧型(弓型)进度条

主要是通过修改Flutter 默认Slider的渲染逻辑,加入了路径渲染 和 路径裁剪。

  • 自行实现难度较高,所以修改官方组件相对简单。

底部卡片动画

animate_do: ^4.2.0 # 动画组件

底部卡片的动画使用的是

dart 复制代码
SlideInUp(
   from: curveHeight,
   animate: controller.slideController?.isCompleted ?? false,
   controller: (slideController) {
       controller.slideController = slideController;
   },
   child: _buildCard(theme),
),

底部弧形卡片

dart 复制代码
/// 底部画刷
class BottomCurvePainter extends CustomPainter {
  BottomCurvePainter(this.backgroundColor);

  /// 背景色
  final Color backgroundColor;

  @override
  void paint(Canvas canvas, Size size) {
    debugPrint("重绘:底部背景-画刷");

    // 贝塞尔曲率
    double bezier = 25;

    Path background = Path()
      ..moveTo(0, bezier)
      ..quadraticBezierTo(size.width / 2, -bezier, size.width, bezier)
      ..lineTo(size.width, size.height)
      ..lineTo(0, size.height)
      ..lineTo(0, bezier)
      ..close();

    //canvas.drawShadow(background, Colors.black, 10, true);
    canvas.clipPath(background);
    canvas.drawColor(backgroundColor, BlendMode.srcIn);
  }

  @override
  bool shouldRepaint(covariant BottomCurvePainter oldDelegate) {
    return backgroundColor != oldDelegate.backgroundColor;
  }
}

音频播放

just_audio: ^0.10.5 # 音频播放

这个组件其实有一些问题,比如

  • 不兼容Windows
  • 没有切换音乐的回调

有可能是文档没查好,如果有不同理解,请在评论区提出。

播放按钮动画

dart 复制代码
AnimatedIcon(
   size: iconSize,
   color: theme.colorScheme.primary,
   icon: AnimatedIcons.play_pause,
   progress: controller ?? AlwaysStoppedAnimation(0),
),

SafeArea安全区域

按钮下方弧形屏幕区域,既是非安全区域

dart 复制代码
/// 底部安全区域
double bottomSafe = MediaQuery.of(context).padding.bottom;

/// 使用SafeAre的minimum就可以设置安全区域。
/// minimum 是最低安全距离的意思,当设备没有安全距离或安全距离小于最小值都会使用设定的最小值。
SliverSafeArea(
  minimum: EdgeInsets.only(
  // left: 15,
  // right: 15,
  bottom: bottomHeight + 20,
),

最后源码也放出来,当然这个项目也会持续更新,如果有喜欢设计的朋友可以联系我,一起参与到后续的开发设计中。 源码地址

相关推荐
Mapmost1 分钟前
数字孪生项目效率翻倍!AI技术实测与场景验证实录
前端
小酒星小杜5 分钟前
在AI时代,技术人应该每天都要花两小时来构建一个自身的构建系统-Input篇
前端·程序员·架构
Cache技术分享13 分钟前
290. Java Stream API - 从文本文件的行创建 Stream
前端·后端
陈_杨16 分钟前
前端成功转鸿蒙开发者真实案例,教大家如何开发鸿蒙APP--ArkTS 卡片开发完全指南
前端·harmonyos
小杨同学4922 分钟前
C 语言实战:枚举类型实现数字转星期(输入 1~7 对应星期几)
前端·后端
陈_杨23 分钟前
前端成功转鸿蒙开发者真实案例,教大家如何开发鸿蒙APP--ArkTS 卡片刷新机制
前端·harmonyos
go_caipu31 分钟前
Vben Admin管理系统集成qiankun微服务(二)
前端·javascript
唐叔在学习34 分钟前
insertAdjacentHTML踩坑实录:AI没搞定的问题,我给搞定啦
前端·javascript·html
超绝大帅哥34 分钟前
Promise为什么比回调函数更好
前端
幸福小宝34 分钟前
uniapp 异型无缝轮播图
前端