android - 在颤振中使用“pushReplacementNamed”后,我无法再次推送此路线
问题描述
我在使用带有 MVVM 模式的 Flutter 中的导航时遇到问题。
我有两个观点:
- 登录
- 仪表板
Navigator.pushReplacementNamed(context, Dashboard)
我从登录导航到仪表板。当用户注销时,我从仪表板导航到 Login withNavigator.pushReplacementNamed(context, Login)
但是我收到以下错误:
一个 Login ViewModel 在被释放后被使用。在 LoginViewModel 上调用 dispose() 后,就不能再使用它了。
我认为当我在处理它后再次调用它时会创建一个 View\Widget ?我应该怎么办?导航没有意义
pushNamed
并将小部件留在小部件树中。
我的登录视图:
import 'package:app/common/routing_contstants.dart';
import 'package:app/core/viewmodels/views/login_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_signin_button/button_view.dart';
import 'package:flutter_signin_button/flutter_signin_button.dart';
import 'package:app/common/colors.dart';
import 'base_view.dart';
class LoginView extends StatefulWidget {
@override
_LoginView createState() => _LoginView();
}
class _LoginView extends State<LoginView> {
final TextEditingController _mailCtr = TextEditingController();
final TextEditingController _passCtr = TextEditingController();
@override
Widget build(BuildContext context) {
return BaseView<LoginViewModel>(
builder: (context, model, child) => Scaffold(
body: Container(
width: double.infinity,
height: double.infinity,
// Add box decoration
decoration: BoxDecoration(
// Box decoration takes a gradient
gradient: LinearGradient(
// Where the linear gradient begins and ends
begin: Alignment.topRight,
end: Alignment.bottomCenter,
// Add one stop for each color. Stops should increase from 0 to 1
stops: [0.2, 0.4, 0.6, 1.0],
colors: [
Colors.deepPurple[800],
Colors.deepPurple[700],
Colors.deepPurple[500],
Theme.of(context).colorScheme.pink,
],
),
),
child: Center(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: <Widget>[
SizedBox(
height: 120,
),
Image.asset(
"assets/images/icon.png",
color: Colors.white,
width: 200,
height: 100,
),
SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: _mailCtr,
decoration: InputDecoration(
hintText: "Email",
hintStyle: TextStyle(color: Colors.grey[500]),
icon: Icon(
Icons.email,
color: Colors.white,
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
),
cursorColor: Colors.white,
style: TextStyle(color: Colors.white),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: _passCtr,
decoration: InputDecoration(
hintText: "Password",
hintStyle: TextStyle(color: Colors.grey[500]),
icon: Icon(
Icons.lock,
color: Colors.white,
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
),
cursorColor: Colors.white,
style: TextStyle(color: Colors.white),
obscureText: true,
),
),
GestureDetector(
onTap: () {},
child: Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: new Text("Forget Password?",
style: Theme.of(context)
.textTheme
.body1
.copyWith(color: Colors.white)),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: SizedBox(
width: double.infinity,
child: OutlineButton(
child: Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: new Text("Login",
style: Theme.of(context)
.textTheme
.title
.copyWith(color: Colors.white))),
onPressed: () async {
var loginSuccess = await model.signInWithEmailAndPassword(context, _mailCtr.text, _passCtr.text);
if (loginSuccess != null) {
Navigator.pushReplacementNamed(context, DashboardRoute);
}
},
// color: Colors.blue,
textColor: Colors.white,
borderSide: BorderSide(color: Colors.white),
)),
),
Padding(
padding: const EdgeInsets.all(0.8),
child: SignInButton(
Buttons.Google,
onPressed: () {},
),
),
Padding(
padding: const EdgeInsets.all(0.8),
child: SignInButton(
Buttons.Facebook,
onPressed: () {},
),
),
SizedBox(
height: 100,
),
],
),
),
)),
),
),
);
}
}
我的仪表板视图:
import 'package:app/common/routing_contstants.dart';
import 'package:app/core/viewmodels/views/dashboard_view_model.dart';
import 'package:flutter/material.dart';
import 'package:app/common/colors.dart';
import 'base_view.dart';
class DashboardView extends StatefulWidget {
@override
_DashboardView createState() => _DashboardView();
}
class _DashboardView extends State<DashboardView> {
@override
Widget build(BuildContext context) {
return BaseView<DashboardViewModel>(
builder: (context, model, child) => Scaffold(
body: Container(
width: double.infinity,
height: double.infinity,
// Add box decoration
decoration: BoxDecoration(
// Box decoration takes a gradient
gradient: LinearGradient(
// Where the linear gradient begins and ends
begin: Alignment.topRight,
end: Alignment.bottomCenter,
// Add one stop for each color. Stops should increase from 0 to 1
stops: [0.3, 0.7, 0.4, 0.3],
colors: [
Theme.of(context).colorScheme.blue,
Theme.of(context).colorScheme.darkBlue,
Theme.of(context).colorScheme.pink,
Colors.pink[600],
],
),
),
child: Center(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: <Widget>[
SizedBox(height: 32.0),
SizedBox(
height: 50.0,
child: _signOutButton(context, model),
),
SizedBox(height: 30.0),
SizedBox(
height: 100,
),
],
),
),
),
),
),
),
);
}
Widget _signOutButton(context, DashboardViewModel model) {
return OutlineButton(
child: Container(
margin: EdgeInsets.symmetric(vertical: 10),
child: new Text("Logout",
style: Theme.of(context)
.textTheme
.title
.copyWith(color: Colors.white))),
onPressed: () async {
await model.signOut(context).then(
(_) => {
Navigator.pushReplacementNamed(context, LoginRoute)
},
);
},
// color: Colors.blue,
textColor: Colors.white,
borderSide: BorderSide(color: Colors.white),
);
}
}
我的基本视图:
import 'package:app/common/locator.dart';
import 'package:app/core/viewmodels/base_model.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class BaseView<T extends BaseModel> extends StatefulWidget {
final Widget Function(BuildContext context, T model, Widget child) builder;
final Function(T) onModelReady;
BaseView({this.builder, this.onModelReady});
@override
_BaseViewState<T> createState() => _BaseViewState<T>();
}
class _BaseViewState<T extends BaseModel> extends State<BaseView<T>> {
T model = getIt<T>();
@override
void initState() {
if (widget.onModelReady != null) {
widget.onModelReady(model);
}
super.initState();
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<T>(
create: (context) => model,
child: Consumer<T>(builder: widget.builder));
}
}
解决方案
用户工厂而不是 RegisterLazySingleton。
推荐阅读
- reactjs - 缩短反应中的多行 setState 代码
- c# - 非静态字段、方法或属性需要对象引用
- javascript - 添加播放器后激光不射击
- scala - Apache Ignite 使用 sbt 与 scala-spark 集成
- java - 用 camel_case_01 替换 camelCase01
- java - 关于jar文件的问题和疑问
- javascript - 如何允许用户将文件从 html FileAPI 沙箱移动/下载到他的首选位置?
- node.js - Material-ui AppBar。滚动时更改颜色。反应
- django - 如何在 django rest 框架的 serilaizer 中获取 lookup_url_kwarg
- c# - PHP 的 utf8_decode 和 C# 的 Encoding.UTF8.GetString 为相同的输入返回不同的输出