【问题标题】:Flutter - How to enable AnimatedOpacity automatically?Flutter - 如何自动启用 AnimatedOpacity?
【发布时间】:2019-05-26 08:12:53
【问题描述】:

我正在创建一个仪表板,其中包含两个小部件文本和两个容器的补间动画。但是,我想让两个Container的不透明度从不可见慢慢变为可见......所以我使用了AnimatedOpacity。但我不知道该怎么做......

任何帮助将不胜感激..

class _IntroState extends State<Intro> with SingleTickerProviderStateMixin {
  Animation animation;
  AnimationController animationController;

   @override
   void initState() {
     super.initState();
      animationController = AnimationController(
        duration: Duration(seconds: 2),
        vsync: this,
     );

    animation = Tween(begin: -1.0, end: 0.0).animate(CurvedAnimation(
        parent: animationController, curve: Curves.fastOutSlowIn));
    animationController.forward();
  }

  @override
  Widget build(BuildContext context) {
    bool _visible = false;
    final double width = MediaQuery.of(context).size.width;

  return AnimatedBuilder(
      animation: animationController,
      builder: (BuildContext context, Widget child) {
         return Scaffold(
           //BODDY
            body: ListView(
              hildren:<Widget>[
                 new Stack(
                   children: <Widget>[
                     new Transform(
                       //ANIMATED OPACITY
                       new AnimatedOpacity(
                          opacity: _visible ? 0.0 : 1.0,
                          duration: Duration(milliseconds: 500),
                          child: new Padding(
                            padding: const EdgeInsets.symmetric(
                                  horizontal: 12.0),
                            child: new Row(
                               children: <Widget>[
                                  Expanded(
                                   child: Row(
                                     children: <Widget>[
                                       child: Padding(
                                         padding: const EdgeInsets.symmetric(horizontal: 8.0),
                                          child: Container(
                                            child: Column(
                                              children: <Widget>[
                                                //THIS THE CONTAINER
                                                new Container(. . .),
                                                new Container(. . .)

【问题讨论】:

  • _visible 应该是您所在州的字段。你应该setState
  • setState 是否可以在没有 onTap 或 GestureDetector 的情况下使用?
  • 当然可以,这是一个可以随时调用的简单方法。我会将 _visible 置于状态并在 initState 中更改其值。
  • 如果把_visible改成initState,就不会出现“淡入”动画了。
  • 你是对的,我的意思是 setState,正如上面 Remi 所提到的。但是当我在阅读代码时,我感到困惑并写了 initState。人为错误:)

标签: dart flutter flutter-animation


【解决方案1】:

使用FadeTransition 小部件代替AnimatedOpacity。这使您可以手动控制动画:

  @override
  Widget build(BuildContext context) {
    return FadeTransition(
      opacity: animationController.drive(CurveTween(curve: Curves.easeOut)),
      child: ...,
    );
  }

【讨论】:

【解决方案2】:

我完全推荐使用上面@boformer 的答案。

但是,我玩弄了您的代码,并想向您展示如何调用 setState 来触发 AnimatedOpacity,因此您可以看到它在没有 onTapGestureDetector 的情况下工作,正如您在上面的cmets。

我得到了你的代码并开始使用它。我所做的是,只需将状态侦听器添加到您的动画控制器以及控制器完成时。我在setState 中触发了可见性布尔值。然后它会改变容器的可见性。

// When animation finished change the visibility.
animationController.addStatusListener((status){
  if (status == AnimationStatus.completed) {
    setState(() {
      // This is opposite, because it's implemented opposite in your code.
      _visible = false;
    });
  }
});

【讨论】:

【解决方案3】:

对于希望在页面呈现后自动淡化小部件并仍想使用AnimatedOpacity 的任何人,您可以在 WidgetsBinding 的 addPostFrameCallback 回调中调用更改不透明度的状态。

将此代码放在您的initState 中。

WidgetsBinding.instance.addPostFrameCallback((_) {
    setState(() {
        _opacity = 1;
    });
});

【讨论】:

【解决方案4】:

要使StatelessWidgetStatefulWidget 在创建时自动淡入,TweenAnimationBuilder 提供了一个更简单的解决方案:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return TweenAnimationBuilder<double>(
        tween: Tween<double>(begin: 0.0, end: 1.0),
        curve: Curves.ease,
        duration: const Duration(seconds: 1),
        builder: (BuildContext context, double opacity, Widget? child) {
          return Opacity(
              opacity: opacity,
              child: Container(width: 20, height: 20, color: Colors.red)
          );
    });
  }
}

完整示例请参见我的 Codepen:https://codepen.io/atok/pen/BaZVRPr

最好的问候

【讨论】:

    猜你喜欢
    • 2021-12-10
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    • 2020-03-26
    • 2021-08-22
    • 1970-01-01
    相关资源
    最近更新 更多