我正在开发一个使用flutter的音频播放器应用程序,我使用on_audio_query package从存储中获取音频文件,使用just_audio package作为音频播放器。
我想知道如何创建类似于此图中所示的条形图
先谢了
mw3dktmi1#
我给你写了一个解决方案https://dartpad.dev/?id=491a65532b2f92590c71a48be4836135
在我的例子中,你可以使用一个流来更新播放按钮周围的进度指示器。看看我的getSecondsFromCurrentMinute方法。用你的包中的流替换它。完整代码:
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), ], ), ); } }
dohp0rv52#
您可以使用Slider小部件来制作进度条。
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); }, ),
并将duration和position的值放入initState()
duration
position
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; }); });
2条答案
按热度按时间mw3dktmi1#
我给你写了一个解决方案https://dartpad.dev/?id=491a65532b2f92590c71a48be4836135
在我的例子中,你可以使用一个流来更新播放按钮周围的进度指示器。看看我的
getSecondsFromCurrentMinute
方法。用你的包中的流替换它。完整代码:
dohp0rv52#
您可以使用
Slider
小部件来制作进度条。并将
duration
和position
的值放入initState()