Commit 764aaf37 authored by skeyboy's avatar skeyboy

语音播放动画

parent 02675894
...@@ -64,7 +64,7 @@ class _DefaultMessageTextState extends State<DefaultMessageText> { ...@@ -64,7 +64,7 @@ class _DefaultMessageTextState extends State<DefaultMessageText> {
controller: controller, controller: controller,
menuBuilder: () => _buildLongPressMenu(widget.message), menuBuilder: () => _buildLongPressMenu(widget.message),
barrierColor: Colors.transparent, barrierColor: Colors.transparent,
position: PreferredPosition.bottom, // position: PreferredPosition.bottom,
pressType: PressType.longPress, pressType: PressType.longPress,
child: Column( child: Column(
crossAxisAlignment: widget.isOwnMessage crossAxisAlignment: widget.isOwnMessage
......
import 'package:flutter/material.dart';
/**
GestureDetector(
onTap: () {
voiceImageAnimationController.reverse();
},
child: VoiceImageAnimation(
assetList: [
"images/left_voice_1.png",
"images/left_voice_2.png",
"images/left_voice_3.png"
],
controller: voiceImageAnimationController,
width: 100,
height: 100),
),
*/
class VoiceImageAnimationController extends ChangeNotifier {
bool isPlaying = false;
void reverse() {
isPlaying = !isPlaying;
notifyListeners();
}
void startAnimation() {
isPlaying = true;
notifyListeners();
}
void endAnimation() {
isPlaying = false;
notifyListeners();
}
}
class VoiceImageAnimation extends StatefulWidget {
List<String> assetList;
int interval = 200;
double width, height;
VoiceImageAnimationController? controller;
VoiceImageAnimation(
{Key? key,
required this.assetList,
required this.controller,
required this.width,
required this.height})
: super(key: key);
@override
State<VoiceImageAnimation> createState() => _VoiceImageAnimationState();
}
class _VoiceImageAnimationState extends State<VoiceImageAnimation>
with SingleTickerProviderStateMixin {
bool isPlaying = false;
// 动画控制
late Animation<double> _animation;
late AnimationController _controller;
int interval = 200;
List<Widget> images = [];
@override
void initState() {
// TODO: implement initState
for (int index = 0; index < widget.assetList.length; index++) {
images.add(Image.asset(
widget.assetList[index],
width: widget.width,
height: widget.height,
));
}
final int imageCount = widget.assetList.length;
final int maxTime = interval * imageCount;
_controller = AnimationController(
duration: Duration(milliseconds: maxTime), vsync: this);
_controller.addStatusListener((status) {
if (status == AnimationStatus.completed) {
_controller.forward(from: 0.0);
}
});
_animation = Tween<double>(begin: 0.0, end: imageCount.toDouble())
.animate(_controller)
..addListener(() {
setState(() {});
});
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
if (mounted) {
widget.controller ??= VoiceImageAnimationController();
widget.controller?.addListener(() {
setState(() {});
});
_controller.forward();
}
});
super.initState();
}
@override
void dispose() {
// TODO: implement dispose
widget.controller?.dispose();
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
if ((widget.controller?.isPlaying ?? false) == false) {
return Stack(alignment: Alignment.center, children: [
Image.asset(
widget.assetList[2],
width: widget.width,
height: widget.height,
)
]);
} else {
int ix = _animation.value.floor() % widget.assetList.length;
List<Widget> images = [];
// 把所有图片都加载进内容,否则每一帧加载时会卡顿
for (int i = 0; i < widget.assetList.length; ++i) {
if (i != ix) {
images.add(Image.asset(
widget.assetList[i],
width: 0,
height: 0,
));
}
}
images.add(Image.asset(
widget.assetList[ix],
width: widget.width,
height: widget.height,
));
return Stack(
alignment: Alignment.center,
children: images,
);
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment