【问题标题】:Flutter: animate border color of a containerFlutter:容器的动画边框颜色
【发布时间】:2021-03-30 12:27:23
【问题描述】:

是否可以用 Flutter 做类似的事情?如果是怎么办?我需要在容器周围绘制动画吗?

【问题讨论】:

    标签: flutter flutter-layout flutter-animation


    【解决方案1】:

    是的,简单的方法是为painterCustom Paint 设置动画。请记住,要为画家设置动画,bool shouldRepaint(BorderPainter oldDelegate) 必须返回 true

    这里我的路径可能看起来很复杂,原因是我对整个动画使用了单个控制器。您可以使用多个控制器制作分段动画,以单独为每个元素设置动画。

    完整代码重现:

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Border Animation',
          home: HomePage(),
        );
      }
    }
    
    class HomePage extends StatefulWidget {
      const HomePage({
        Key key,
      }) : super(key: key);
    
      @override
      _HomePageState createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage>
        with SingleTickerProviderStateMixin {
      AnimationController controller;
      Animation<double> animation;
    
      @override
      void initState() {
        controller = AnimationController(
          vsync: this,
          duration: Duration(
            milliseconds: 2000,
          ),
        );
        animation = controller
          ..addListener(() {
            setState(() {});
          })
          ..addStatusListener((status) {
            if (status == AnimationStatus.completed) {
              controller.reset();
            } else if (status == AnimationStatus.dismissed) {
              controller.forward();
            }
          });
        controller.forward();
        super.initState();
      }
    
      @override
      void dispose() {
        controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.black,
          appBar: AppBar(
            title: Text('Material App Bar'),
          ),
          body: Center(
            child: AnimatedBuilder(
              animation: animation,
              builder: (context, child) {
                return CustomPaint(
                  foregroundPainter: BorderPainter(controller.value),
                  child: Container(
                    color: Colors.red,
                    width: 150,
                    height: 150,
                  ),
                );
              },
            ),
          ),
        );
      }
    }
    
    class BorderPainter extends CustomPainter {
      final double controller;
    
      BorderPainter(this.controller);
    
      @override
      void paint(Canvas canvas, Size size) {
        double _sh = size.height; // For path shortage
        double _sw = size.width;  // For path shortage
        double _line = 30.0;  // Length of the animated line
        double _c1 = controller * 2; // Controller value for top and left border.
        double _c2 = controller >= 0.5 ? (controller - 0.5) * 2 : 0; // Controller value for bottom and right border.
    
        Paint paint = Paint()
          ..color = Colors.white
          ..strokeWidth = 3
          ..style = PaintingStyle.stroke;
    
        Path _top = Path()
          ..moveTo(_sw * _c1 > _sw ? _sw : _sw * _c1, 0)
          ..lineTo(_sw * _c1 + _line >= _sw ? _sw : _sw * _c1 + _line, 0);
    
        Path _left = Path()
          ..moveTo(0, _sh * _c1 > _sh ? _sh : _sh * _c1)
          ..lineTo(0, _sh * _c1 + _line >= _sh ? _sh : _sh * _c1 + _line);
    
        Path _right = Path()
          ..moveTo(_sw, _sh * _c2)
          ..lineTo(
              _sw,
              _sh * _c2 + _line > _sh
                  ? _sh
                  : _sw * _c1 + _line >= _sw
                      ? _sw * _c1 + _line - _sw
                      : _sh * _c2);
    
        Path _bottom =  Path()
          ..moveTo(_sw * _c2, _sh)
          ..lineTo(
              
              _sw * _c2 + _line > _sw
                  ? _sw
                  : _sh * _c1 + _line >= _sh
                      ? _sh * _c1 + _line - _sh
                      : _sw * _c2, _sh);
    
            
    
        canvas.drawPath(_top, paint);
        canvas.drawPath(_left, paint);
        canvas.drawPath(_right, paint);
        canvas.drawPath(_bottom, paint);
      }
    
      @override
      bool shouldRepaint(BorderPainter oldDelegate) => true;
    
      @override
      bool shouldRebuildSemantics(BorderPainter oldDelegate) => false;
    }
    
    

    【讨论】:

      猜你喜欢
      • 2013-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-25
      • 2018-10-24
      • 1970-01-01
      相关资源
      最近更新 更多