如何在 Flutter 中对流中的 UI 更改进行动画处理?

问题描述 投票:0回答:1

我能找到的所有动画小部件示例都需要有状态小部件,并在调用 setState 来更改字段值时以动画方式进行更改。有没有办法将 StreamBuilder 与动画结合起来?

我尝试将动画小部件放入流构建器的构建方法中,但这不会产生任何动画,因为它会在每次更改时创建一个新的动画小部件,并且看不到任何过渡。我本来希望在动画小部件上找到一个可选的“流”参数,以告诉它在新值到达流时进行动画处理。我可以向此示例添加什么以使其在值更改之间产生动画效果? (例如简单的线性过渡)。

import 'dart:math';

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
            child: StreamBuilder(
                stream: DataStreamSource().dataStream,
                initialData: 50,
                builder: (BuildContext buildContext, AsyncSnapshot<int> snapshot) {
                  return InkWell(onTap: DataStreamSource().generate, child: Container(height: snapshot.data?.toDouble(), width: snapshot.data?.toDouble(), color: Colors.deepOrange));
                })));
  }
}

class DataStreamSource {
  static final DataStreamSource _instance = DataStreamSource._internal();
  factory DataStreamSource() => _instance;
  DataStreamSource._internal();

  final BehaviorSubject<int> _dataController = BehaviorSubject();
  Stream<int> get dataStream => _dataController.stream;

  void generate() => _dataController.add(Random().nextInt(100) + 100);
}
flutter animation stream behaviorsubject flutter-streambuilder
1个回答
0
投票

在您提供的示例中,您只需将

Container
更改为
AnimatedContainer
即可“正常工作”:

StreamBuilder(
  stream: DataStreamSource().dataStream,
  initialData: 50,
  builder: (BuildContext buildContext, AsyncSnapshot<int> snapshot) {
    return InkWell(
      onTap: DataStreamSource().generate,
      child: AnimatedContainer(
        duration: const Duration(milliseconds: 500),
        height: snapshot.data?.toDouble(),
        width: snapshot.data?.toDouble(),
        color: Colors.deepOrange,
      ),
    );
  },
);

这里是 Dartpad 工作示例

流触发重建后,Flutter 将

AnimatedContainer
的状态与
AnimatedContainer
的新实例进行匹配。然后该状态发现宽度和高度值已更改并执行动画。 Flutter 能够将状态与 widget 的每个更新版本实例相匹配,因为 widget 树每次都具有相同的结构。如果您有一个更复杂的用例,涉及可以替换的小部件、具有多个相同类型的同级部件等,您可能需要使用键来保持一切正常工作。请参阅此视频了解更多详情。

© www.soinside.com 2019 - 2024. All rights reserved.