如何将动画添加到作为基于 Flutter 中的 firebase AuthState 的路由器工作的 StreamBuilder?

How to add animation to a StreamBuilder that is working as a router based on firebase AuthState in Flutter?

在我的 main.dart 中,我 returning Router() 小部件作为我的 home。在 Router.dart 中,我基本上有 StreamBuilderFirebaseAuth.instance.onAuthStateChanged 作为 stream 和 returns 根据用户的 AuthState 显示哪个小部件。如果 connectionStatewaiting 我 return Splash 作为自定义启动画面。如果 snapshot.hasData 我 return Home 小部件,如果不是我 return Login 小部件。

现在我的问题是整个路由工作正常,但我需要动画转换。假设从 Splash 到任何小部件的过渡 Splash 都会淡出。从 LoginHome 过渡 Login 将向左滑动。从 HomeLogin 过渡 Login 将从左侧滑动。我怎样才能使这些变化动起来?

这些是我的文件:

main.dart

import 'router.dart';
void main() => runApp(Main());

class Main extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
       //Theme
      ),
      home: Router(),
    );
  }
}

router.dart

import 'login.dart';
import 'home.dart';

class Router extends StatefulWidget {
  _RouterState createState() => _RouterState();
}

class _RouterState extends State<Router> {
  @override
  Widget build(BuildContext context){
    return StreamBuilder<FirebaseUser>(
      stream: FirebaseAuth.instance.onAuthStateChanged,
      builder: (BuildContext context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Splash();
        } else {
          if (snapshot.hasData) {
            return Home();
          }
          return Login();
        }
      },
    );
  }
}

class Splash extends StatelessWidget {
  @override
  Widget build(BuildContext context){
    return Scaffold(
      backgroundColor: Theme.of(context).backgroundColor,
      body: Container(
        width: MediaQuery.of(context).size.width,
        child: Center(
          child: Text(
            "Splash"
          ),
        )
      ),
    );
  }
}

提前致谢。

如果需要每个小部件文件,请发表评论。我没有上传它们,因为它们很大并且包含一些秘密。

我遇到了同样的问题。我建议您在 didChangeDependencies() 中使用 stream.listen 而不是 StreamBuilder。并且根据 Auth 状态将 Navigator.pushReplacement() 与过渡动画一起使用。

示例代码:

class Router extends StatefulWidget {
  _RouterState createState() => _RouterState();
}

class _RouterState extends State<Router> {
  @override
  void didChangeDependencies() {
    FirebaseAuth.instance.onAuthStateChanged.listen((firebaseUser) {
      if (firebaseUser != null) {
        _next(context, Home());
      }
      _next(context, Login());
    });
    super.didChangeDependencies();
  }

  _next(BuildContext context, Widget nextPage) {
    Navigator.of(context).pushReplacement(
      PageRouteBuilder(
        opaque: false,
        pageBuilder: (BuildContext context, Animation<double> animation,
            Animation<double> secondaryAnimation) {
          return nextPage;
        },
        transitionsBuilder: (BuildContext context, Animation<double> animation,
            Animation<double> secondaryAnimation, Widget child) {
          return FadeTransition(
            opacity: Tween<double>(
              begin: 0.0,
              end: 1.0,
            ).animate(animation),
            child: child,
          );
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Splash();
  }
}

要在 streambuilder 中的小部件之间执行动画转换,很简单,只需使用名为 AnimatedSwitcher 的小部件即可:

@override
Widget build(BuildContext context) {
 return StreamBuilder(
  stream: FirebaseAuth.instance.onAuthStateChanged,
  builder: (BuildContext context, snapshot) {
    return AnimatedSwitcher(
      duration: Duration(seconds: 1),
      child: _getMainWidget(snapshot, context),
    );
  },
);
}

这里我们使用 AnimatedSwitcher 在 AnimatedSwitcher 的子项发生变化时为过渡设置动画,默认动画是淡入淡出动画,但您可以通过向小部件传递 TransitionBuilder 作为参数