I am developing an audio player application using flutter, I m using on_audio_query package to fetch audio files from storage, and just_audio package for the audio player.
I want to know how to create something like the bar that is shown in this image

thanks in advance
I wrote one solution in a dartpad for you: https://dartpad.dev/?id=491a65532b2f92590c71a48be4836135

As in my example, you can use a stream to update the progress indicator around the play button. Look at my getSecondsFromCurrentMinute method. Replace this with the stream from your package.
Full code:
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),
],
),
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With