我的应用程序需要自动启动生物识别登录并根据结果导航到页面。 这是常见的需求,我遵循与this solution
类似的建议下面的代码
class _LoginPageState extends State<LoginPage> {
@override
Widget build(BuildContext context) {
final UserModel userModel = Provider.of<UserModel>(context);
return (userModel.biometricLoginEnabled && !userModel.isAuthenticated)
? _attemptBiometricAuthentication(context, userModel)
: _buildLoginForm(context, userModel);
}
Widget _attemptBiometricAuthentication(
BuildContext context, UserModel userModel) {
return FutureBuilder(
future: _initiateBiometricAuthentication(),
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data == true) {
// make sure user is marked as authenticated
userModel.setAuthenticationWithoutNotification(true);
return HomePage(); // <-- WHOA!!
} else if (snapshot.hasData && snapshot.data == false) {
// we should have an updated error from _initiateBiometricAuthentication
return _buildLoginForm(context, userModel);
} else if (snapshot.hasError) {
return _buildLoginForm(context, userModel);
} else {
// we're waiting
return Container(
constraints: BoxConstraints(
maxHeight: MediaQuery.of(context).size.height,
minHeight: MediaQuery.of(context).size.height,
),
alignment: Alignment.center,
child: SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Image(
image: AssetImage('images/Logo.png'),
fit: BoxFit.fitWidth,
),
CircularProgressIndicator(),
],
),
),
);
}
},
);
}
}
如果身份验证成功,问题出在return HomePage()
行。
如果调用setState()并发生重建,则将HomePage
内的LoginPage
重建。路由也有些混乱,因为该应用程序认为它在路由/login
上,但实际上在/home
上。
我觉得我在自动触发路由中完全丢失了一些东西。
答案 0 :(得分:1)
您需要侦听Future方法的结果并导航到其他页面。 (永远不要在构建窗口小部件内进行操作。)
演示:
代码示例:
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class FutureNavigation extends StatefulWidget {
@override
_FutureNavigationState createState() => _FutureNavigationState();
}
class _FutureNavigationState extends State<FutureNavigation> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Demo Future Navigator"),
),
body: buildBody(context),
);
}
Widget buildBody(BuildContext context) {
return FutureBuilder(
future: _login(),
builder: (context, snapshot) {
return Center(child: CircularProgressIndicator());
},
);
}
Future<String> _login() async {
await Future.delayed(Duration(seconds: 3)).then((value) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (BuildContext context) {
return HomePage();
},
),
);
});
return "Logined";
}
}