首页 > 解决方案 > 如何在 Flutter 中基于 Firebase AuthState 向作为路由器工作的 StreamBuilder 添加动画?

问题描述

在我的main.dart我将Router()小部件作为我的home. 在Router.dart我基本上有StreamBuilderwhich 接受FirebaseAuth.instance.onAuthStateChangedstream根据用户的AuthState. 如果connectionStatewaitingSplash作为自定义启动画面返回。如果snapshot.hasData我返回Home小部件,如果不是,我返回Login小部件。

现在我的问题是整个路由工作正常,但我需要为过渡设置动画。假设从Splash到任何小部件过渡Splash都会淡出。从LoginHome过渡Login将向左滑动。从HomeLogin过渡Login将从左侧滑动。如何为这些更改设置动画?

这些是我的文件:

主要.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(),
    );
  }
}

路由器.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"
          ),
        )
      ),
    );
  }
}

提前致谢。

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

标签: flutterfirebase-authenticationflutter-animation

解决方案


我遇到了同样的问题。我建议您在 didChangeDependencies() 中使用 stream.listen 而不是 StreamBuilder。并且您使用 Navigator.pushReplacement() 和取决于 Auth 状态的过渡动画。

示例代码:

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();
  }
}

推荐阅读