如何将动画添加到作为基于 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
中,我基本上有 StreamBuilder
将 FirebaseAuth.instance.onAuthStateChanged
作为 stream
和 returns 根据用户的 AuthState
显示哪个小部件。如果 connectionState
是 waiting
我 return Splash
作为自定义启动画面。如果 snapshot.hasData
我 return Home
小部件,如果不是我 return Login
小部件。
现在我的问题是整个路由工作正常,但我需要动画转换。假设从 Splash
到任何小部件的过渡 Splash
都会淡出。从 Login
到 Home
过渡 Login
将向左滑动。从 Home
到 Login
过渡 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 作为参数
在我的 main.dart
中,我 returning Router()
小部件作为我的 home
。在 Router.dart
中,我基本上有 StreamBuilder
将 FirebaseAuth.instance.onAuthStateChanged
作为 stream
和 returns 根据用户的 AuthState
显示哪个小部件。如果 connectionState
是 waiting
我 return Splash
作为自定义启动画面。如果 snapshot.hasData
我 return Home
小部件,如果不是我 return Login
小部件。
现在我的问题是整个路由工作正常,但我需要动画转换。假设从 Splash
到任何小部件的过渡 Splash
都会淡出。从 Login
到 Home
过渡 Login
将向左滑动。从 Home
到 Login
过渡 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 作为参数