在整块重建中颤动的动画容器

时间:2020-07-18 22:55:05

标签: flutter animation bloc

我知道flutter有一些很棒的动画小部件,但似乎找不到我想要的东西。我有一个相当简单的设置...

  • 屏幕(有状态的小部件)使用blocbuilder检索某些列表数据,并将其与布尔值minified一起传递给小部件。
  • 该小部件返回每个列表项的容器。
  • 根据minifed
  • ,容器的内容有所不同
  • minified的值是通过从屏幕上的按钮调用setstate来更改的。

这里是minified = false,这里是minified = true

在第二个屏幕中,所有框都相同,但是内容更改为索引而不是全文。目前,这两个状态之间的过渡只是一个快速的捕捉,但是我希望每个有色容器在其内容更改时缩小并移动到新位置。

这可能吗?我尝试使用英雄小部件和动画容器,但都没有任何效果。

这是代码: 屏幕

class PatternScreen extends StatefulWidget {
  @override
  _PatternScreenState createState() => _PatternScreenState();
}

class _PatternScreenState extends State<PatternScreen> {
  bool minified = false;

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: BlocBuilder<SpeechModelBloc, SpeechModelState>(builder: (context, state) {
        if (state is SpeechModelInitialState) {
          return Center(
              child: Column(
            children: <Widget>[CircularProgressIndicator(), Text('Loading Speech Pattern...')],
          ));
        }
        if (state is LessonModelLoadedState) {
          return Column(
            children: <Widget>[
              FlatButton(
                child: minified == false ? Text('Minify') : Text('Maxify'),
              onPressed: () {
                  setState(() {
                    minified = !minified;
                  });
              },
              ),
              BlocksViewWidget(script: state.script, comp: minified),
            ],
          );
        }

小部件:绘制屏幕设置状态时,我希望对其进行动画处理的是'ComputerRow'和'HumanRow'小部件。

class BlocksViewWidget extends StatelessWidget {
  final TTSScript script;
  final bool comp;

  BlocksViewWidget({Key key, this.script, this.comp}) : super(key: key);

  @override
  Widget build(BuildContext context) {
      return SafeArea(
        child: Wrap(
          children: <Widget>[
            for ( var i in script.scriptList ) chatRow(i),
          ],
        ),
      );
  }

  Widget chatRow (List<dynamic> scriptItem) {
    return scriptItem[3] == "repeating" ? humanRow(scriptItem) : computerRow(scriptItem);
  }

  Widget humanRow (List<dynamic> scriptItem) {
    return Container(
      alignment: comp == false ? Alignment.centerRight : null,
      child: Padding(
        padding: const EdgeInsets.only(
            right: 8.0, left: 8.0, top: 4.0, bottom: 4.0),
        child: ClipRRect(
          borderRadius: BorderRadius.only(
              bottomLeft: Radius.circular(15),
              bottomRight: Radius.circular(0),
              topLeft: Radius.circular(15),
              topRight: Radius.circular(15)),
          child: Container(
            color: Colors.deepPurple,
            // margin: const EdgeInsets.only(left: 10.0),
            child: Wrap(children: <Widget>[
              Padding(
                padding: const EdgeInsets.only(right: 12.0, left: 12.0, top: 8.0, bottom: 8.0),
                child: comp == false ? Text(scriptItem[2]) : Text(scriptItem[1]) ,
              ),

            ]),
          ),
        ),
      ),
    );
  }


  Widget computerRow (List<dynamic> scriptItem) {
    return Container(
        child: Padding(
          padding:
          const EdgeInsets.only(right: 8.0, left: 8.0, top: 8.0, bottom: 8.0),
          child: ClipRRect(
            borderRadius: BorderRadius.only(
                bottomLeft: Radius.circular(0),
                bottomRight: Radius.circular(15),
                topLeft: Radius.circular(15),
                topRight: Radius.circular(15)),
            child: Container(
              color: Colors.blueGrey,
              child: Wrap(children: <Widget>[
                Padding(
                  padding: const EdgeInsets.only(right: 8.0, left: 8.0, top: 8.0, bottom: 8.0),
                  child: comp == false ? Text(scriptItem[2]) : Text(scriptItem[1]) ,
                ),
              ]),
            ),
          ),
        ));
  }
}

**

更新

**

好吧,所以我开始重建它,有点地方了,但是部分仍然无法正常工作。

我现在在Wrap小部件中有三个简单的容器。两个animated containers可以在两个状态之间完美地进行动画处理,但是由于它们使应用程序崩溃,因此我无法在这些状态上使用nulldouble.infinity作为大小...因此我必须手动设置大小。不好,因为我希望较小的尺寸仅适合内容(文本小部件)。

我可以使用AnimatedSize而不是AnimatedContainer来执行此操作...但是,它只能从null到double进行动画处理。无穷大...相反,这是一个突然的变化,而不是动画平滑变化。另外,Flexible小部件抱怨放在Wrap小部件内。

这是新代码:

class SpeechModelView extends StatefulWidget {

  SpeechModelView({Key key}) : super(key: key);

  @override
  _SpeechModelViewState createState() => _SpeechModelViewState();
}

class _SpeechModelViewState extends State<SpeechModelView> with TickerProviderStateMixin {

  @override
  Widget build(BuildContext context) {
    bool size = true;
    return Scaffold(
      body: SafeArea(
        child: CustomScrollView(
          slivers: <Widget>[
            SliverToBoxAdapter(
              child: Wrap(
                children: <Widget>[
                  AnimatedContainer(
                    color: Colors.red,
                    duration: Duration(milliseconds: 1000),
                    height: 50,
                    width: size ? 50 : MediaQuery. of(context). size. width,
                    child: size ? Text('Short Text') : Text('Much much much much much longer text.... could be a whole long paragraph')
                  ),
                  AnimatedContainer(
                    color: Colors.amber,
                    duration: Duration(milliseconds: 1000),
                    height: 50,
                    width: size ? 50 : MediaQuery. of(context). size. width,
                  ),
                  Flexible(
                    child: AnimatedSize(
                      vsync: this,
                      duration: Duration(milliseconds: 600),
                      child: Container(
                        height: 50,
                        width: size ? null : double.infinity,
                        color: Colors.red,
                          child: size ? Text('Short Text') : Text('Much much much much much longer text. .... could be a whole long paragraph')),
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

任何有关如何处理null大小动画的想法将不胜感激。呆了好几个小时,有点失落了。

0 个答案:

没有答案