初始化
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// 音频波形动画组件
|
||||
/// 用于显示音频播放时的动态波形效果
|
||||
class AudioWaveView extends StatefulWidget {
|
||||
/// 波形高度
|
||||
final double height;
|
||||
|
||||
/// 波形颜色
|
||||
final Color color;
|
||||
|
||||
/// 动画持续时间
|
||||
final Duration duration;
|
||||
|
||||
/// 动画曲线
|
||||
final Curve curve;
|
||||
|
||||
/// 波形条之间的间距
|
||||
final double margin;
|
||||
|
||||
/// 波形条的宽度
|
||||
final double width;
|
||||
|
||||
/// 波形条的数量
|
||||
final int barCount;
|
||||
|
||||
const AudioWaveView({
|
||||
super.key,
|
||||
this.height = 12,
|
||||
this.margin = 3,
|
||||
this.width = 1.5,
|
||||
this.color = const Color(0xffF68804),
|
||||
this.duration = const Duration(seconds: 5),
|
||||
this.curve = Curves.easeInOut,
|
||||
this.barCount = 3,
|
||||
});
|
||||
|
||||
@override
|
||||
State<AudioWaveView> createState() => _AudioWaveViewState();
|
||||
}
|
||||
|
||||
class _AudioWaveViewState extends State<AudioWaveView>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late AnimationController _controller;
|
||||
late List<Animation<double>> _animations;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initializeAnimations();
|
||||
}
|
||||
|
||||
/// 初始化动画
|
||||
void _initializeAnimations() {
|
||||
_controller = AnimationController(
|
||||
vsync: this,
|
||||
duration: widget.duration,
|
||||
);
|
||||
|
||||
_animations = _createWaveAnimations();
|
||||
_controller.repeat();
|
||||
}
|
||||
|
||||
/// 创建波形动画列表
|
||||
List<Animation<double>> _createWaveAnimations() {
|
||||
const int sequenceCount = 15;
|
||||
final List<Animation<double>> animations = [];
|
||||
|
||||
for (int i = 0; i < widget.barCount; i++) {
|
||||
final source = _generateRandomSequence(sequenceCount);
|
||||
|
||||
final tweenSequence = TweenSequence<double>(
|
||||
List.generate(sequenceCount, (index) {
|
||||
return TweenSequenceItem<double>(
|
||||
tween: Tween<double>(
|
||||
begin: source[index],
|
||||
end: source[index + 1],
|
||||
),
|
||||
weight: 100.0 / sequenceCount,
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
animations.add(
|
||||
tweenSequence.animate(
|
||||
CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: widget.curve,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return animations;
|
||||
}
|
||||
|
||||
/// 生成随机序列
|
||||
List<double> _generateRandomSequence(int count) {
|
||||
final random = Random();
|
||||
final source = List.generate(count, (_) => random.nextDouble());
|
||||
source.add(source.first); // 确保循环
|
||||
return source;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnimatedBuilder(
|
||||
animation: _controller,
|
||||
builder: (context, child) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: _buildWaveBars(),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建波形条列表
|
||||
List<Widget> _buildWaveBars() {
|
||||
final List<Widget> bars = [];
|
||||
|
||||
for (int i = 0; i < widget.barCount; i++) {
|
||||
if (i > 0) {
|
||||
bars.add(SizedBox(width: widget.margin));
|
||||
}
|
||||
|
||||
bars.add(
|
||||
WaveBar(
|
||||
color: widget.color,
|
||||
width: widget.width,
|
||||
height: _animations[i].value * widget.height,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return bars;
|
||||
}
|
||||
}
|
||||
|
||||
/// 单个波形条组件
|
||||
class WaveBar extends StatelessWidget {
|
||||
final double width;
|
||||
final double height;
|
||||
final Color color;
|
||||
|
||||
const WaveBar({
|
||||
super.key,
|
||||
required this.width,
|
||||
required this.height,
|
||||
required this.color,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: width,
|
||||
height: height,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
borderRadius: BorderRadius.circular(width / 2),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user