Flutter- Flink 按钮

unftdfkk  于 2023-01-14  发布在  Flutter
关注(0)|答案(4)|浏览(151)

我需要一个能引起用户注意的按钮。我想到的第一个想法是添加一个 Flink 动画。我真的不知道该怎么做,但我试着用下面的代码使它工作:

Timer timer = new Timer(new Duration(seconds: 1), () {
  //basic logic to change the color variable here
  setState(() {});
});

很简单,每隔一秒调用一次setState,然后再次创建小部件。
但是它不起作用,计时器只被调用一次,除此之外,在Timer中调用setState在我看来是错误的。
有更好的办法吗?

wlp8pajw

wlp8pajw1#

您可以使用AnimationControllerFadeTransition小部件以简单的方式实现这一点,下面是代码:

class MyBlinkingButton extends StatefulWidget {
    @override
    _MyBlinkingButtonState createState() => _MyBlinkingButtonState();
  }

  class _MyBlinkingButtonState extends State<MyBlinkingButton>
      with SingleTickerProviderStateMixin {
    AnimationController _animationController;

    @override
    void initState() {
      _animationController =
          new AnimationController(vsync: this, duration: Duration(seconds: 1));
      _animationController.repeat(reverse: true);
      super.initState();
    }

    @override
    Widget build(BuildContext context) {
      return FadeTransition(
        opacity: _animationController,
        child: MaterialButton(
          onPressed: () => null,
          child: Text("Text button"),
          color: Colors.green,
        ),
      );
    }

    @override
    void dispose() {
      _animationController.dispose();
      super.dispose();
    }
  }

用法:

main() {
  runApp(
    MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Material(
        child: Center(
          child: MyBlinkingButton(),
        ),
      ),
    ),
  );
}

DartPad example
结果:

pu82cl6c

pu82cl6c2#

你也可以用这种方法来做。我的逻辑有点不同,我用交替的动画。一旦动画完成了,我就回来了。

    • 对视力有好处**

即:
向前-〉向后
向后-〉向前
等等

import 'package:flutter/material.dart';
import 'package:flutter/animation.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Wordpress App',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new BlinkAnimation(),
    );
  }
}

class BlinkAnimation extends StatefulWidget {
  @override
  _BlinkAnimationState createState() => _BlinkAnimationState();
}

class _BlinkAnimationState extends State<BlinkAnimation>
    with SingleTickerProviderStateMixin {
  Animation<Color> animation;
  AnimationController controller;

  initState() {
    super.initState();
    controller = AnimationController(
        duration: const Duration(milliseconds: 500), vsync: this);
    final CurvedAnimation curve =
        CurvedAnimation(parent: controller, curve: Curves.linear);
    animation =
        ColorTween(begin: Colors.white, end: Colors.blue).animate(curve);
    animation.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        controller.reverse();
      } else if (status == AnimationStatus.dismissed) {
        controller.forward();
      }
      setState(() {});
    });
    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: new Text('Blink Animation'),
      ),
      body: new Center(
        child: AnimatedBuilder(
          animation: animation,
          builder: (BuildContext context, Widget child) {
            return new Container(
              child: new RaisedButton(
                color: animation.value,
                onPressed: () {
                  controller.forward();
                },
                child: Text('Blink Animation'),
              ),
            );
          },
        ),
      ),
    );
  }

  dispose() {
    controller.dispose();
    super.dispose();
  }
}
jfgube3f

jfgube3f3#

以下是来自the answer by @nitishk72的示例,但代码更新为null safety和更新的Flutter版本。

结果:

代码:

你可以只把这个复制到DartPad.dev,它就会工作:)

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Blink animation demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: BlinkAnimation(),
    );
  }
}

class BlinkAnimation extends StatefulWidget {
  @override
  _BlinkAnimationState createState() => _BlinkAnimationState();
}

class _BlinkAnimationState extends State<BlinkAnimation>
    with SingleTickerProviderStateMixin {
  late Animation<Color?> animation;
  late AnimationController controller;

  @override
  initState() {
    super.initState();
    controller = AnimationController(
      duration: const Duration(milliseconds: 500),
      vsync: this,
    );
    final CurvedAnimation curve =
        CurvedAnimation(parent: controller, curve: Curves.linear);
    animation =
        ColorTween(begin: Colors.white, end: Colors.blue).animate(curve);
    // Keep the animation going forever once it is started
    animation.addStatusListener((status) {
      // Reverse the animation after it has been completed
      if (status == AnimationStatus.completed) {
        controller.reverse();
      } else if (status == AnimationStatus.dismissed) {
        controller.forward();
      }
      setState(() {});
    });
    // Remove this line if you want to start the animation later
    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Blink Animation'),
      ),
      body: Center(
        child: AnimatedBuilder(
          animation: animation,
          builder: (BuildContext context, Widget? child) {
            return Container(
              color: animation.value,
              padding: const EdgeInsets.all(8.0),
              child: InkWell(
                onTap: () {
                  // Start the animation or do something else on click
                  // controller.forward();
                  print('button does something!');
                },
                child: const Text('Blink Animation'),
              ),
            );
          },
        ),
      ),
    );
  }

  @override
  dispose() {
    controller.dispose();
    super.dispose();
  }
}
jdgnovmf

jdgnovmf4#

目前的答案是伟大的,但不包括不透明 Flink (重复淡入,淡出),您可以使用以下小部件,如果这是您的目标:

class BlinkAnimation extends StatefulWidget {
  final Widget child;

  const BlinkAnimation({
    Key? key,
    required this.child,
  }) : super(key: key);

  @override
  State<BlinkAnimation> createState() => _BlinkAnimationState();
}

class _BlinkAnimationState extends State<BlinkAnimation>
    with SingleTickerProviderStateMixin {
  late final AnimationController controller = AnimationController(
    duration: const Duration(seconds: 2),
    vsync: this,
  )..repeat(reverse: true);
  late final Animation<double> animation = CurvedAnimation(
    parent: controller,
    curve: Curves.easeIn,
  );

  @override
  Widget build(BuildContext context) {
    return FadeTransition(opacity: animation, child: widget.child);
  }

  @override
  dispose() {
    controller.dispose();
    super.dispose();
  }
}

基于FadeTransition

相关问题