Flutter迷你播放器插件miniplayer的使用

发布于 1周前 作者 ionicwang 来自 Flutter

Flutter迷你播放器插件miniplayer的使用

描述

Pub

miniplayer是一个轻量级的Flutter包,通过提供一个带有当前高度和进度百分比的构建函数来简化迷你播放器的创建。该小部件响应点击和拖动手势,并且高度可定制。

什么是迷你播放器?

迷你播放器常见于Spotify和YouTube等媒体应用程序中。迷你播放器可以展开和最小化,并在最小化时保持在屏幕上,直到用户关闭它。

Demo

Demo

使用方法

Stack(
  children: <Widget>[
    YourApp(),
    Miniplayer(
      minHeight: 70,
      maxHeight: 370,
      builder: (height, percentage) {
        return Center(
          child: Text('$height, $percentage'),
        );
      },
    ),
  ],
),

选项

Parameter Implementation Example
onDismiss
Miniplayer(
   onDismiss: () {
      //Handle onDismissed here
   }, 
),

| onDismiss 如果设置了onDismiss,迷你播放器可以被关闭。 | | valueNotifier |

final ValueNotifier<double> playerExpandProgress =
    ValueNotifier(playerMinHeight);
    
Miniplayer(
   valueNotifier: playerExpandProgress, 
),

| valueNotifier 允许您使用带有当前进度的全局ValueNotifier。这可以用于隐藏BottomNavigationBar。 | | controller |

final MiniplayerController controller = MiniplayerController();
    
Miniplayer(
   controller: controller, 
),

controller.animateToHeight(state: PanelState.MAX);

| - |

持久性

按照使用方法中描述的方法实现迷你播放器(例如将其包装在Scaffold体中的Stack内)会正常工作,但有一些缺点。如果您通过Navigator.push推送新屏幕,迷你播放器将消失。我们希望的是一个持久存在的迷你播放器。

如果要实现持久性,您可以选择两种嵌入方式之一,具体取决于您的用例。第一种方法仅适用于简单的应用程序。如果您想使用对话框或其他持久的小部件(如BottomNavigationBar),则应使用第二种方法

第一种方法(简单)

builder方法中使用Stack

import 'package:flutter/material.dart';
import 'package:miniplayer/miniplayer.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Miniplayer example',
      theme: ThemeData(
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
      builder: (context, child) { // Important part
        return Stack(
          children: [
            child,
            Miniplayer(
              minHeight: 70,
              maxHeight: 370,
              builder: (height, percentage) {
                if(percentage > 0.2)
                  //return Text('!mini');
                else 
                  //return Text('mini');
              },
            ),
          ],
        );
      },
    );
  }
}

第二种方法(高级)

结合Stack和自定义Navigator使用:

import 'package:flutter/material.dart';
import 'package:miniplayer/miniplayer.dart';

void main() => runApp(MyApp());

final _navigatorKey = GlobalKey();

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Miniplayer example',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primaryColor: Color(0xFFFAFAFA),
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MiniplayerWillPopScope(
      onWillPop: () async {
        final NavigatorState navigator = _navigatorKey.currentState;
        if (!navigator.canPop()) return true;
        navigator.pop();

        return false;
      },
      child: Scaffold(
        body: Stack(
          children: <Widget>[
            Navigator(
              key: _navigatorKey,
              onGenerateRoute: (RouteSettings settings) => MaterialPageRoute(
                settings: settings,
                builder: (BuildContext context) => FirstScreen(),
              ),
            ),
            Miniplayer(
              minHeight: 70,
              maxHeight: 370,
              builder: (height, percentage) => Center(
                child: Text('$height, $percentage'),
              ),
            ),
          ],
        ),
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: 0,
          fixedColor: Colors.blue,
          items: [
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Home',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.mail),
              label: 'Messages',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.person),
              label: 'Profile',
            )
          ],
        ),
      ),
    );
  }
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Demo: FirstScreen')),
      body: Container(
        constraints: BoxConstraints.expand(),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => SecondScreen()),
              ),
              child: const Text('Open SecondScreen'),
            ),
            ElevatedButton(
              onPressed: () => Navigator.of(context, rootNavigator: true).push(
                MaterialPageRoute(builder: (context) => ThirdScreen()),
              ),
              child: const Text('Open ThirdScreen with root Navigator'),
            ),
          ],
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Demo: SecondScreen')),
      body: Center(child: Text('SecondScreen')),
    );
  }
}

class ThirdScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Demo: ThirdScreen')),
      body: Center(child: Text('ThirdScreen')),
    );
  }
}

Roadmap

  • [x] 提供更好的示例
  • [x] 添加处理水平手势的选项(像Spotify那样)
  • [x] 重写onDismiss的API(破坏性更改)
    • [x] 标记onDismiss为已弃用

更多关于Flutter迷你播放器插件miniplayer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter迷你播放器插件miniplayer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用miniplayer插件来创建一个迷你播放器的示例代码。假设你已经在pubspec.yaml文件中添加了miniplayer依赖并运行了flutter pub get

1. 添加依赖

首先,确保你的pubspec.yaml文件中包含以下依赖:

dependencies:
  flutter:
    sdk: flutter
  miniplayer: ^最新版本号  # 请替换为实际可用的最新版本号

2. 导入插件

在你的Dart文件中导入miniplayer插件:

import 'package:flutter/material.dart';
import 'package:miniplayer/miniplayer.dart';

3. 配置和使用MiniPlayer

下面是一个简单的示例,展示了如何配置和使用MiniPlayer。这个示例假设你有一个音频或视频URL,并希望在应用程序中显示一个迷你播放器。

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter MiniPlayer Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MiniPlayerDemo(),
    );
  }
}

class MiniPlayerDemo extends StatefulWidget {
  @override
  _MiniPlayerDemoState createState() => _MiniPlayerDemoState();
}

class _MiniPlayerDemoState extends State<MiniPlayerDemo> {
  MiniPlayerController? _miniPlayerController;

  @override
  void initState() {
    super.initState();
    // 初始化MiniPlayerController
    _miniPlayerController = MiniPlayerController(
      context,
      data: MiniPlayerData(
        title: 'Demo Audio',
        imageUrl: 'https://via.placeholder.com/150', // 封面图片URL
        mediaUrl: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3', // 媒体文件URL
        isPlaying: false,
      ),
      miniPlayerBuilder: (context, controller) {
        return Material(
          color: Colors.transparent,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Image.network(
                controller.data?.imageUrl ?? '',
                width: 100,
                height: 100,
              ),
              SizedBox(height: 10),
              Text(
                controller.data?.title ?? '',
                style: TextStyle(color: Colors.white),
              ),
              SizedBox(height: 10),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  IconButton(
                    icon: Icon(
                      controller.isPlaying ? Icons.pause : Icons.play_arrow,
                      color: Colors.white,
                    ),
                    onPressed: () {
                      controller.togglePlayPause();
                    },
                  ),
                  SizedBox(width: 20),
                  IconButton(
                    icon: Icon(Icons.stop, color: Colors.white),
                    onPressed: () {
                      controller.stop();
                    },
                  ),
                ],
              ),
            ],
          ),
        );
      },
    );

    // 显示迷你播放器
    _miniPlayerController?.show();
  }

  @override
  void dispose() {
    _miniPlayerController?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter MiniPlayer Demo'),
      ),
      body: Center(
        child: Text('Swipe down from the top to reveal the mini player'),
      ),
    );
  }
}

4. 运行应用程序

确保你的设备或模拟器已连接,然后在终端中运行flutter run来启动应用程序。你应该能够在应用程序中看到一个简单的迷你播放器,当你从屏幕顶部向下滑动时可以显示它。

注意事项

  • MiniPlayerController用于控制迷你播放器的行为,如播放、暂停和停止。
  • MiniPlayerData包含迷你播放器显示所需的数据,如标题、封面图片URL和媒体文件URL。
  • miniPlayerBuilder是一个函数,用于构建迷你播放器的UI。

这个示例代码展示了如何使用miniplayer插件来创建一个基本的迷你播放器。你可以根据需要进行进一步的自定义和扩展。

回到顶部