如何为可扩展的 Flutter 小部件设置动画以将其滑出屏幕

Posted

技术标签:

【中文标题】如何为可扩展的 Flutter 小部件设置动画以将其滑出屏幕【英文标题】:How to animate expandable Flutter widget to slide it out of the screen 【发布时间】:2019-07-15 13:32:30 【问题描述】:

我有两个连续的可扩展按钮占据了所有屏幕宽度。在左键单击时,我希望左键占据整个屏幕宽度,右键从屏幕右侧消失。以下是我目前取得的成就:

正如您所注意到的,当没有足够的空间来渲染它时,右边的按钮会在最后被压扁。我只是希望它继续移出屏幕而不改变它的宽度。我可以通过为按钮设置一行文本来实现这一点,但我希望该解决方案一般适用于所有小部件(看起来右侧有足够的空间来呈现它)。

目前的解决方案:

import 'package:flutter/material.dart';

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

class TestAnimation extends StatefulWidget 
  @override
  _TestAnimationState createState() => _TestAnimationState();


class _TestAnimationState extends State<TestAnimation> with SingleTickerProviderStateMixin 
  AnimationController _animationController;
  Animation _animation;

  @override
  void initState() 
    super.initState();
    _animationController = AnimationController(duration: Duration(seconds: 2), vsync: this);
    _animation = IntTween(begin: 100, end: 0).animate(_animationController);
    _animation.addListener(() => setState(() ));
  

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Row(
            children: <Widget>[
              Expanded(
                flex: 100,
                child: OutlineButton(
                  child: Text("Left"),
                  onPressed: () 
                    if (_animationController.value == 0.0) 
                      _animationController.forward();
                     else 
                      _animationController.reverse();
                    
                  ,
                ),
              ),
              Expanded(
                flex: _animation.value,
                // Uses to hide widget when flex is going to 0
                child: SizedBox(
                  width: 0,
                  child: OutlineButton(
                    child: Text(
                      "Right",
                    ),
                    onPressed: () ,
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  

【问题讨论】:

【参考方案1】:

更新:其他方式是为 Text Widget 定义 TextOverflow

Expanded(
                flex: _animation.value,
                // Uses to hide widget when flex is going to 0
                child: SizedBox(
                  width: 0.0,
                  child: OutlineButton(
                    child: Text(
                      "Right",
                      overflow: TextOverflow.ellipsis, // Add this
                    ),
                    onPressed: () ,
                  ),
                ),
              )

这个(右键被压扁)可以在FittedBox小部件的帮助下解决。

import 'package:flutter/material.dart';

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

class TestAnimation extends StatefulWidget 
  @override
  _TestAnimationState createState() => _TestAnimationState();


class _TestAnimationState extends State<TestAnimation> with SingleTickerProviderStateMixin 
  AnimationController _animationController;
  Animation _animation;

  @override
  void initState() 
    super.initState();
    _animationController = AnimationController(duration: Duration(seconds: 2), vsync: this);
    _animation = IntTween(begin: 100, end: 0).animate(_animationController);
    _animation.addListener(() => setState(() ));
  

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Row(
            children: <Widget>[
              Expanded(
                flex: 100,
                child: OutlineButton(
                  child: Text("Left"),
                  onPressed: () 
                    if (_animationController.value == 0.0) 
                      _animationController.forward();
                     else 
                      _animationController.reverse();
                    
                  ,
                ),
              ),
              Expanded(
                flex: _animation.value,
                // Uses to hide widget when flex is going to 0
                child: SizedBox(
                  width: 0.0,
                  child: OutlineButton(
                    child: FittedBox(    //Add this
                      child: Text(
                        "Right",
                      ),
                    ),
                    onPressed: () ,
                  ),
                ),
              )
            ],
          ),
        ),
      ),
    );
  

输出:

【讨论】:

谢谢,看起来不错的解决方法,但仍需要修改动画小部件(更改按钮的内部子级)。 @AlekseyMasny - 用更简单的方式更新了答案。我建议FittedBox - 因为它可以应用于任何小部件。 @anmol.majhail.if you please see my question on animation picture from right to left ***.com/questions/66418815/… 如果?我需要为我的 ListView 中的每个元素实现这个。我无法为每个元素设置类参数。

以上是关于如何为可扩展的 Flutter 小部件设置动画以将其滑出屏幕的主要内容,如果未能解决你的问题,请参考以下文章

Flutter - 如何用动画扩展小部件?

如何为 StreamBuilder 生成的小部件设置动画?

在 Flutter 中,您如何制作动画以将容器从 0 高度扩展到其内容的高度?

Flutter:如何用 Provider 播放动画?

如何为小部件 Flutter 添加垂直间距

Flutter - 我可以用 Hero 包装每个小部件来为它们设置动画吗