Blame view

lib/pages/practice/widgets/shake_widget.dart 2.77 KB
45c862fd   吴启风   feat:闯关交互优化-答错晃动、...
1
2
3
4
  import 'package:flutter/material.dart';
  
  import '../../../utils/log_util.dart';
  
56b412f5   吴启风   feat:扬声器播放动画组件封装
5
  ///左右晃动组件,用于答错场景
45c862fd   吴启风   feat:闯关交互优化-答错晃动、...
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  class ShakeWidget extends StatefulWidget {
    final Widget child;
    final int shakeCount;
    final double shakeOffset;
    final Duration duration;
    final bool shouldShake;
  
    const ShakeWidget({
      Key? key,
      required this.child,
      this.shakeCount = 2,
      this.shakeOffset = 10.0,
      this.duration = const Duration(milliseconds: 500),
      this.shouldShake = false,
    }) : super(key: key);
  
    @override
    _ShakeWidgetState createState() => _ShakeWidgetState();
  }
  
  class _ShakeWidgetState extends State<ShakeWidget> with SingleTickerProviderStateMixin {
    late AnimationController _controller;
    late Animation<double> _animation;
642081ad   吴启风   feat:lottie动画加载优化...
29
    static const String TAG = "ShakeWidget";
45c862fd   吴启风   feat:闯关交互优化-答错晃动、...
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  
    @override
    void initState() {
      super.initState();
      _controller = AnimationController(
        vsync: this,
        duration: widget.duration,
      );
  
      _animation = TweenSequence([
        TweenSequenceItem(
          tween: Tween(begin: 0.0, end: widget.shakeOffset)
              .chain(CurveTween(curve: Curves.easeInOut)),
          weight: 1,
        ),
        TweenSequenceItem(
          tween: Tween(begin: widget.shakeOffset, end: -widget.shakeOffset)
              .chain(CurveTween(curve: Curves.easeInOut)),
          weight: 1,
        ),
        TweenSequenceItem(
          tween: Tween(begin: -widget.shakeOffset, end: widget.shakeOffset)
              .chain(CurveTween(curve: Curves.easeInOut)),
          weight: 1,
        ),
        TweenSequenceItem(
          tween: Tween(begin: widget.shakeOffset, end: -widget.shakeOffset)
              .chain(CurveTween(curve: Curves.easeInOut)),
          weight: 1,
        ),
        TweenSequenceItem(
          tween: Tween(begin: -widget.shakeOffset, end: 0.0)
              .chain(CurveTween(curve: Curves.easeInOut)),
          weight: 1,
        ),
      ]).animate(_controller);
    }
  
    @override
    void didUpdateWidget(covariant ShakeWidget oldWidget) {
      super.didUpdateWidget(oldWidget);
642081ad   吴启风   feat:lottie动画加载优化...
71
      Log.d("$TAG didUpdateWidget widget.shouldShake=${widget.shouldShake} oldWidget.shouldShake=${oldWidget.shouldShake} isAnimating=${_controller.isAnimating}");
45c862fd   吴启风   feat:闯关交互优化-答错晃动、...
72
      // if (widget.shouldShake && !oldWidget.shouldShake) {
642081ad   吴启风   feat:lottie动画加载优化...
73
      if (widget.shouldShake && !_controller.isAnimating) {
45c862fd   吴启风   feat:闯关交互优化-答错晃动、...
74
        _controller.forward(from: 0.0);
642081ad   吴启风   feat:lottie动画加载优化...
75
76
      } else if (!widget.shouldShake && _controller.isAnimating) {
        _controller.stop();
45c862fd   吴启风   feat:闯关交互优化-答错晃动、...
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
      }
    }
  
    @override
    void dispose() {
      _controller.dispose();
      super.dispose();
    }
  
    @override
    Widget build(BuildContext context) {
      return AnimatedBuilder(
        animation: _animation,
        builder: (context, child) {
          return Transform.translate(
            offset: Offset(_animation.value, 0),
            child: widget.child,
          );
        },
        child: widget.child,
      );
    }
  }