import 'dart:async'; import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_sound/flutter_sound.dart'; /// 扬声器输出等级可视化 class SpeakerWave extends StatefulWidget { final FlutterSoundPlayer audioPlayer; final double width; final double height; final Color color; final bool isPlaying; SpeakerWave({ required this.audioPlayer, this.isPlaying = false, this.width = 250.0, this.height = 40.0, this.color = Colors.blue, }); @override _SpeakerWaveState createState() => _SpeakerWaveState(); } class _SpeakerWaveState extends State { StreamSubscription? _waveformSubscription; int _randomWaveform = 0; static const _itemHeight = 10.0; static const _itemCount = 5; @override void initState() { super.initState(); print("监听扬声器输出:${widget.audioPlayer}"); /// 监听扬声器输出 _waveformSubscription = widget.audioPlayer.onProgress?.listen((PlaybackDisposition data) { setState(() { _randomWaveform = Random().nextInt(_itemCount); }); if (data.duration - data.position < Duration(milliseconds: 500)) { setState(() { _randomWaveform = 0; }); } }); } @override void dispose() { super.dispose(); _waveformSubscription?.cancel(); _waveformSubscription = null; } @override Widget build(BuildContext context) { return Container( width: widget.width, height: widget.height, child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( "扬声器输出:", style: TextStyle( height: 1, color: Colors.black87, ), ), if (widget.isPlaying) ...[ for (var i = 0; i < _randomWaveform; i++) Expanded( child: buildActiveItem(), ), for (var i = 0; i < _itemCount - _randomWaveform; i++) Expanded( child: buildInactiveItem(), ), ] else ...[ for (var i = 0; i < _itemCount; i++) Expanded( child: buildInactiveItem(), ), ] ], ), ); } Widget buildActiveItem() { return Container( height: _itemHeight, margin: EdgeInsets.symmetric(horizontal: 3), decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(5)), color: widget.color, ), ); } Widget buildInactiveItem() { return Container( height: _itemHeight, margin: EdgeInsets.symmetric(horizontal: 3), decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(5)), color: Colors.grey[300], ), ); } }