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,
),

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

相关推荐
前端老宋Running7 小时前
前端防抖与节流一篇讲清楚
前端·面试
ejinxian7 小时前
Rust UI 框架GPUI 与 Electron 的对比
前端·javascript·electron
小马哥learn7 小时前
Vue3 + Electron + Node.js 桌面项目完整开发指南
前端·javascript·electron
znhy@1237 小时前
CSS3属性(三)
前端·css·css3
凌泽7 小时前
「让规范驱动代码」——我如何用 Cursor + Spec Kit 在5小时内完成一个智能学习分析平台的
前端
omnibots7 小时前
瑞萨SDK编译linux时,make menuconfig报错
linux·服务器·前端·嵌入式硬件
魔云连洲7 小时前
前端树形结构过滤算法
前端·算法
前端小咸鱼一条8 小时前
19. React的高阶组件
前端·javascript·react.js
狮子座的男孩8 小时前
js基础:10、函数对象方法(call/apply)、arguments类数组对象、Date对象、Math工具类、包装类、字符串方法、正则表达式
前端·javascript·正则表达式·包装类·字符串方法·arguments·date对象