I'm trying to create a range slider on top of a Row of Containers which should create an audio waveform, but I have no idea where to even start...
The main issue is that the range slider sits right on top of the row of containers and it should change their colors on the "selected" section.
Here's what I currently have:
The code to create the image and details.
class BeatLyricsPage extends StatefulWidget {
final Beat beat;
BeatLyricsPage(this.beat);
@override
_BeatLyricsPageState createState() => _BeatLyricsPageState(beat);
}
class _BeatLyricsPageState extends State<BeatLyricsPage> {
final Beat beat;
final _kPicHeight = 190.0;
// used in _buildPageHeading to add the beat key and beat bpm
Widget _buildBeatInfoItem(String text) => DecoratedBox(
decoration: BoxDecoration(
border: Border.all(color: MyColor.white, width: 1.0),
borderRadius: BorderRadius.circular(4.0),
),
child: Padding(
padding: EdgeInsets.symmetric(vertical: 3.0, horizontal: 12.0),
child: Text(text, style: TextStyle(color: MyColor.white, fontSize: 10.0, fontWeight: FontWeight.w600)),
),
);
final _kAudioControlsWidth = 180.0;
final _kAudioControlsHeight = 36.0;
final _kAudioControlsMainButtonSize = 56.0;
Widget _buildAudioControls(BuildContext context) => Positioned(
left: (MediaQuery.of(context).size.width / 2) - (_kAudioControlsWidth / 2),
top: _kPicHeight - (_kAudioControlsHeight / 2),
child: Stack(
overflow: Overflow.visible,
children: [
Container(
width: _kAudioControlsWidth,
height: _kAudioControlsHeight,
decoration: BoxDecoration(color: MyColor.darkGrey, borderRadius: BorderRadius.circular(100.0)),
padding: EdgeInsets.symmetric(horizontal: LayoutSpacing.sm),
child: Row(
children: [
CButtonLike(beatId: beat.id),
Spacer(),
GestureDetector(
behavior: HitTestBehavior.opaque,
child: Icon(BeatPulseIcons.cart),
onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => LicenseOptionsPage(beat))),
),
],
),
),
// ****** MAIN BUTTON (Play/Pause) ******
Positioned(
left: (_kAudioControlsWidth / 2) - (_kAudioControlsMainButtonSize / 2),
top: (_kAudioControlsHeight - _kAudioControlsMainButtonSize) / 2,
child: Container(
height: _kAudioControlsMainButtonSize,
width: _kAudioControlsMainButtonSize,
decoration: BoxDecoration(
gradient: LinearGradient(begin: Alignment.topLeft, colors: [MyColor.primary, Color(0xFFf80d0a)]),
borderRadius: BorderRadius.circular(100.0)),
child: CButtonPlay(),
),
)
],
),
);
Widget _buildWaveForm() {
// creates a random list of doubles, "fake data"
var rng = Random();
final List waveFormData = [];
for (var i = 0; i < 90; i++) {
waveFormData.add(rng.nextInt(45).toDouble());
}
// player bloc
final playerBloc = BlocProvider.getPlayerBloc(context);
// renders
return Container(
height: _kPicHeight,
padding: EdgeInsets.symmetric(vertical: LayoutSpacing.xxxl),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
// current playing second
StreamBuilder<double>(
stream: playerBloc.playingSecond,
initialData: 0.0,
builder: (_, playingSecondSnapshot) {
// current beat playing
return StreamBuilder<Beat>(
stream: playerBloc.playingBeat,
builder: (_, playingBeatSnapshot) {
final playingBeat = playingBeatSnapshot.data;
// if the beat playing is the same as the beat selected for the lyrics, show playing seconds
if (playingBeat?.id == beat.id)
return Text(secondsToTime(playingSecondSnapshot.data), style: MyFontStyle.sizeXxs);
// otherwise show 0:00
else
return Text(secondsToTime(0), style: MyFontStyle.sizeXxs);
},
);
},
),
SizedBox(width: LayoutSpacing.xs),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: waveFormData
.map((waveFormDataIndex) => Container(
height: waveFormDataIndex > 5.0 ? waveFormDataIndex : 5.0,
width: 2,
color: MyColor.white,
margin: EdgeInsets.only(right: 1),
))
.toList(),
),
SizedBox(width: LayoutSpacing.xs),
Text(secondsToTime(beat.length), style: MyFontStyle.sizeXxs),
],
),
);
}
Widget _buildPageHeading(BuildContext context, {@required String imageUrl}) => Stack(
children: [
Column(
children: [
Hero(
tag: MyKeys.makePlayerCoverKey(beat.id),
child: Opacity(
opacity: 0.3,
child: Container(
height: _kPicHeight,
decoration: BoxDecoration(
image: DecorationImage(image: CachedNetworkImageProvider(imageUrl), fit: BoxFit.cover),
),
),
),
),
Container(color: MyColor.background, height: LayoutSpacing.xl)
],
),
Padding(
padding: EdgeInsets.all(LayoutSpacing.xs),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
_buildBeatInfoItem(beat.key),
SizedBox(width: 4.0),
_buildBeatInfoItem('${beat.bpm} BPM'),
],
),
),
_buildAudioControls(context),
_buildWaveForm(),
],
);
}


