代码之家  ›  专栏  ›  技术社区  ›  Hardik Mehta

Flutter创建类似顶部空间的动画应用程序

  •  0
  • Hardik Mehta  · 技术社区  · 1 年前

    想在flutter中实现类似Headspace应用程序的动画效果。 enter image description here

    1 回复  |  直到 1 年前
        1
  •  3
  •   MendelG    1 年前

    后果

    enter image description here

    密码

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            body: Center(
              child: HeadspaceWidget(),
            ),
          ),
        );
      }
    }
    
    class HeadspaceWidget extends StatefulWidget {
      @override
      _HeadspaceWidgetState createState() => _HeadspaceWidgetState();
    }
    
    class _HeadspaceWidgetState extends State<HeadspaceWidget>
        with SingleTickerProviderStateMixin {
      late AnimationController _controller;
      late Animation<double> _circleSizeAnimation;
      late Animation<double> _circleMovementAnimation;
      late Animation<double> _textMovementAnimation;
      late Animation<double> _textOpacityAnimation;
    
      @override
      void initState() {
        super.initState();
        _controller = AnimationController(
          duration: const Duration(seconds: 1),
          vsync: this,
        );
    
        _circleSizeAnimation = Tween<double>(begin: 200.0, end: 50.0).animate(
          CurvedAnimation(
            parent: _controller,
            curve: Interval(
              0.0,
              0.5, // Halfway through the animation
              curve: Curves.easeOut,
            ),
          ),
        );
    
        _circleMovementAnimation = Tween<double>(begin: 0.0, end: -20.0).animate(
          CurvedAnimation(
            parent: _controller,
            curve: Interval(
              0.5,
              1.0,
              curve: Curves.easeInOut,
            ),
          ),
        );
    
        _textMovementAnimation = Tween<double>(begin: 15, end: 20.0).animate(
          CurvedAnimation(
            parent: _controller,
            curve: Interval(
              0.5,
              1.0,
              curve: Curves.easeInOut,
            ),
          ),
        );
    
        _textOpacityAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(
          CurvedAnimation(
            parent: _controller,
            curve: Interval(
              0.5, // Start fading in the text after the circle finishes shrinking
              1.0,
              curve: Curves.easeIn,
            ),
          ),
        );
      }
    
      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return AnimatedBuilder(
          animation: _controller,
          builder: (context, child) {
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Row(
                  children: [
                    ElevatedButton(
                      onPressed: () {
                        _controller.forward();
                      },
                      child: Text('Start Animation'),
                    ),
                    ElevatedButton(
                      onPressed: () {
                        _controller.reverse();
                      },
                      child: Text('Reverse Animation'),
                    ),
                  ],
                ),
                SizedBox(height: 20),
                Row(
                  mainAxisSize: MainAxisSize.min,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Center(
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        mainAxisSize: MainAxisSize.min,
                        children: <Widget>[
                          Transform.translate(
                            offset: Offset(_circleMovementAnimation.value + 20, 0),
                            child: Container(
                              width: _circleSizeAnimation.value,
                              height: _circleSizeAnimation.value,
                              decoration: BoxDecoration(
                                color: Colors.orange,
                                shape: BoxShape.circle,
                              ),
                            ),
                          ),
                          Transform.translate(
                            offset: Offset(_textMovementAnimation.value, 0),
                            child: AnimatedOpacity(
                              opacity: _textOpacityAnimation.value,
                              duration: Duration
                                  .zero,
                              child: Text(
                                'headspace',
                                style: TextStyle(
                                  fontSize: 24,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ],
            );
          },
        );
      }
    }