| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- import 'package:flutter/material.dart';
- class ShimmerEffect extends StatefulWidget {
- final Widget child;
- final Duration duration; // 控制光线滑动的速度
- final List<Color> colors; // 渐变的颜色列表 与 stops 配合使用,长度必须一致
- final Alignment begin; // 光线起点
- final Alignment end; // 光线终点
- final double shimmerWidth; // 光线宽度参数
- final Duration delay; // 每次执行完后的延迟时间
- const ShimmerEffect({
- super.key,
- required this.child,
- this.duration = const Duration(seconds: 2),
- this.colors = const [
- Colors.transparent,
- Colors.white60,
- Colors.transparent,
- ],
- this.begin = const Alignment(-1, -1),
- this.end = const Alignment(1, 1),
- this.shimmerWidth = 0.1,
- this.delay = const Duration(seconds: 1),
- });
- @override
- _ShimmerEffectState createState() => _ShimmerEffectState();
- }
- class _ShimmerEffectState extends State<ShimmerEffect>
- with SingleTickerProviderStateMixin {
- late AnimationController _controller;
- @override
- void initState() {
- super.initState();
- // 初始化动画控制器
- _controller = AnimationController(
- vsync: this,
- duration: widget.duration,
- );
- _startAnimation();
- }
- void _startAnimation() 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 AnimatedBuilder(
- animation: _controller,
- builder: (context, child) {
- final shimmerPosition = _controller.value * 2 - 1;
- return ClipRRect(
- borderRadius: BorderRadius.circular(8),
- child: ShaderMask(
- shaderCallback: (bounds) {
- return LinearGradient(
- begin: widget.begin,
- end: widget.end,
- colors: widget.colors,
- stops: [
- shimmerPosition - widget.shimmerWidth,
- shimmerPosition,
- shimmerPosition + widget.shimmerWidth,
- ],
- ).createShader(bounds);
- },
- blendMode: BlendMode.screen,
- child: widget.child,
- ));
- },
- child: widget.child,
- );
- }
- }
|