如何在Flutter音频播放器应用程序中显示音乐条

zc0qhyus  于 2022-11-17  发布在  Flutter
关注(0)|答案(2)|浏览(367)

我正在开发一个使用flutter的音频播放器应用程序,我使用on_audio_query package从存储中获取音频文件,使用just_audio package作为音频播放器。

我想知道如何创建类似于此图中所示的条形图

先谢了

mw3dktmi

mw3dktmi1#

我给你写了一个解决方案https://dartpad.dev/?id=491a65532b2f92590c71a48be4836135

在我的例子中,你可以使用一个流来更新播放按钮周围的进度指示器。看看我的getSecondsFromCurrentMinute方法。用你的包中的流替换它。
完整代码:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: Colors.black,
      ),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        backgroundColor: Colors.black,
        body: Align(
          alignment: Alignment.bottomCenter,
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  // Get the the seconds from current minute.
  //
  // TODO: Make this your actual progress indicator
  Stream<int> getSecondsFromCurrentMinute() async* {
    final now = DateTime.now();
    final seconds = now.second;
    yield seconds;
    await Future.delayed(Duration(seconds: 1 - seconds));
    yield* getSecondsFromCurrentMinute();
  }

  @override
  Widget build(BuildContext context) {
    return FractionallySizedBox(
      heightFactor: .15,
      widthFactor: 1,
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // Song cover
          Container(
            width: 40,
            height: 40,
            decoration: BoxDecoration(
                color: Colors.white, borderRadius: BorderRadius.circular(10)),
          ),

          // Padding
          SizedBox(width: 15),

          // Title and artist
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // Title
              Text(
                "AUD-20190208-WA0007",
                style: Theme.of(context).textTheme.headline5,
              ),
              // Artist
              Text(
                "Unknown artist",
                style: Theme.of(context)
                    .textTheme
                    .bodyText2
                    ?.copyWith(color: Colors.grey.withOpacity(.6)),
              ),
            ],
          ),

          // Padding between first 2 columns and Icons
          Expanded(child: SizedBox.expand()),

          //
          // Play button and progress indicator
          //
          StreamBuilder<int>(
              stream: getSecondsFromCurrentMinute(),
              builder: (context, AsyncSnapshot<int> snapshot) {
                double percentageOfSecond = (snapshot.data ?? 0) / 60;

                return Container(
                  width: 40,
                  height: 40,
                  child: Stack(
                    children: [
                      // the circle showing progress
                      Positioned(
                        top: 0,
                        left: 0,
                        child: Container(
                          width: 40,
                          height: 40,
                          child: CircularProgressIndicator(
                            value: percentageOfSecond,
                            valueColor: AlwaysStoppedAnimation<Color>(
                              Colors.red,
                            ),
                            backgroundColor: Colors.red.withOpacity(0.15),
                          ),
                        ),
                      ),
                      // the play arrow, inside the circle
                      Positioned(
                        top: 0,
                        left: 0,
                        child: Container(
                          width: 35,
                          height: 35,
                          child: IconButton(
                            icon: Icon(
                              Icons.play_arrow,
                              color: Colors.red,
                            ),
                            onPressed: () {},
                          ),
                        ),
                      ),
                    ],
                  ),
                );
              }),

          SizedBox(width: 8),

          Container(
            width: 40,
            height: 40,
            child: GestureDetector(
              onTap: () {},
              child: Icon(
                Icons.skip_next,
                color: Colors.red,
              ),
            ),
          ),

          //
          SizedBox(width: 8),

          Container(
            width: 40,
            height: 40,
            child: GestureDetector(
              onTap: () {},
              child: Icon(
                Icons.menu,
                color: Colors.red,
                size: 35,
              ),
            ),
          ),

          // Extra padding at the end of the row
          SizedBox(width: 30),
        ],
      ),
    );
  }
}
dohp0rv5

dohp0rv52#

您可以使用Slider小部件来制作进度条。

@override
Widget build(BuildContext context) {
return Slider(
       value: position.inSeconds.toDouble(),
        min: 0.0,
        max: duration.inSeconds.toDouble() ,
        onChanged: (value) async {
                final position = Duration(seconds: value.toInt());
                await player.seek(position);
             },
        ),

并将durationposition的值放入initState()

Duration duration = Duration.zero;
Duration position = Duration.zero;
 @override
  void initState() {
    player.currentPosition.listen((positionValue){
      setState(() {
        position = positionValue;
      });
    });

    player.current.listen((event) {
      setState(() {
        duration =  event.audio.duration;
      });
    });

相关问题