import 'package:flutter/material.dart'; class ShimmerEffect extends StatefulWidget { final Widget child; final Duration duration; // 光效滑动的时间 final Duration delay; // 每轮动画结束后的延迟 final Alignment begin; // 滑动起点 final Alignment end; // 滑动终点 final ImageProvider image; // 外部传入的光效图片 final double shimmerWidthFactor; // 光效图片相对于 child 的宽度 const ShimmerEffect({ super.key, required this.child, required this.image, this.duration = const Duration(seconds: 2), this.delay = const Duration(seconds: 1), this.begin = const Alignment(-1, 0), this.end = const Alignment(1, 0), this.shimmerWidthFactor = 0.2, }); @override State createState() => _ShimmerEffectState(); } class _ShimmerEffectState extends State with SingleTickerProviderStateMixin { late final AnimationController _controller; late final Animation _animation; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: widget.duration, ); _animation = Tween(begin: -1.0, end: 1.0).animate(_controller); _startLoop(); } void _startLoop() async { while (mounted) { await _controller.forward(); _controller.reset(); await Future.delayed(widget.delay); } } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return LayoutBuilder(builder: (context, constraints) { final width = constraints.maxWidth; final shimmerWidth = width * widget.shimmerWidthFactor; return Stack( children: [ widget.child, AnimatedBuilder( animation: _controller, builder: (context, _) { final dx = _animation.value * (width + shimmerWidth); return Positioned( left: dx, top: 0, width: shimmerWidth, height: constraints.maxHeight, child: IgnorePointer( child: Image( image: widget.image, fit: BoxFit.fill, ), ), ); }, ) ], ); }); } }