【发布时间】:2020-09-06 12:29:01
【问题描述】:
我正在尝试使用 Flutter 创建一个 Web 应用程序,但我有一个问题。通过授权后,我需要更改导航栏中的“登录”按钮,据我了解,我需要更改按钮文本并在导航栏中调用 setState,但在我的实现中引发了异常。
AuthPage.dart
import 'package:flutter/material.dart';
import 'package:um/pages/home/app_color.dart';
import 'package:um/scripts/api_client.dart';
import 'package:um/scripts/locator.dart';
import 'NavBarDesktop.dart';
class AuthorizationPageDesktop extends StatefulWidget {
AuthorizationPageDesktop({Key key}) : super(key: key);
@override
_AuthorizationPageDesktopState createState() =>
_AuthorizationPageDesktopState();
}
class _AuthorizationPageDesktopState extends State<AuthorizationPageDesktop> {
TextEditingController _emailController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
bool rememberMe = false;
ApiClient apiClient = ApiClient.getInstance();
ScrollController _scrollController = ScrollController();
PageController _pageController = PageController();
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
child: Padding(
padding: EdgeInsets.only(top: 150, left: 0, right: 0),
child: Column(
children: <Widget>[
Text(
'Авторизация',
style: TextStyle(
fontWeight: FontWeight.w600,
fontSize: 28,
color: textPrimaryColor),
),
SizedBox(
height: 40,
),
_input(Icon(Icons.mail), 'Email', _emailController, false, 15),
SizedBox(
height: 15,
),
_input(Icon(Icons.lock), 'Password', _passwordController, true, 15),
SizedBox(
height: 5,
),
Container(
padding: EdgeInsets.only(left: 20, right: 20),
width: 460,
child: Theme(
data: ThemeData(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
hoverColor: Colors.transparent),
child: CheckboxListTile(
title: Text(
'Запомнить меня',
style: TextStyle(color: textPrimaryColor),
),
value: rememberMe,
onChanged: (bool value) {
setState(() {
rememberMe = value;
});
},
))),
SizedBox(
height: 5,
),
_button('Войти', auth, 15),
SizedBox(
height: 15,
),
Container(
width: 460,
child: Align(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Пройдите ',
style: TextStyle(color: Colors.white, fontSize: 12),
),
Text(
'регистрацию, ',
style: TextStyle(color: linkColor, fontSize: 12),
),
Text(
'если вы этого еще не сделали',
style: TextStyle(color: Colors.white, fontSize: 12),
),
],
)),
),
SizedBox(height: 50),
],
),
)));
}
Widget _input(Icon icon, String hint, TextEditingController controller,
bool obscure, double borderRadius) {
return Container(
width: 460,
height: 50,
padding: EdgeInsets.only(left: 20, right: 20),
child: TextField(
controller: controller,
obscureText: obscure,
style: TextStyle(fontSize: 16, color: Colors.white),
decoration: InputDecoration(
border: OutlineInputBorder(),
isDense: true, // Added this
contentPadding: EdgeInsets.all(8), //
hintStyle: TextStyle(
fontWeight: FontWeight.bold, fontSize: 16, color: Colors.white),
hintText: hint,
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: BorderSide(color: Colors.white, width: 2)),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: BorderSide(color: Colors.white54, width: 1)),
prefixIcon: Padding(
padding: EdgeInsets.only(left: 10, right: 10),
child: IconTheme(
data: IconThemeData(color: Colors.white),
child: icon,
),
)),
),
);
}
Widget _button(String label, void func(), double borderRadius) {
return Container(
width: 460,
padding: EdgeInsets.only(left: 20, right: 20),
child: RaisedButton(
onPressed: () {
apiClient
.authorization(_emailController.text, _passwordController.text)
.then((value) {
func();
});
},
highlightColor: Theme.of(context).primaryColor,
color: buttonPrimaryColor,
child: Text('Войти',
style: TextStyle(
fontWeight: FontWeight.bold,
color: textPrimaryColor,
fontSize: 16)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(borderRadius)),
));
}
void auth() {
var state = navBar<NavBarDesktop>().navBarState;
state.update();
}
}
NavBar.dart
import 'package:flutter/material.dart';
import 'package:um/Widgets/Desktop/AuthPageDesktop.dart';
import 'package:um/Widgets/Desktop/HomePageDesktop.dart';
import 'package:um/Widgets/NavBarItem.dart';
import 'package:um/layout_template/layout_template.dart';
import 'package:um/pages/home/app_color.dart';
import 'package:um/scripts/api_client.dart';
import 'package:um/scripts/locator.dart';
class NavBarDesktop extends StatefulWidget {
NavBarDesktop({Key key}) : super(key: key);
GlobalKey<_NavBarDesktopState> navBarDesktop =
GlobalKey<_NavBarDesktopState>();
_NavBarDesktopState navBarState = new _NavBarDesktopState();
static _NavBarDesktopState of(BuildContext context) {
// print('_NavBarDesktopState -> ${context}');
assert(context != null);
final _NavBarDesktopState result =
// ignore: deprecated_member_use
context.ancestorStateOfType(const TypeMatcher<_NavBarDesktopState>());
// print('_NavBarDesktopState resutl -> ${result}');
return result;
}
@override
_NavBarDesktopState createState() => new _NavBarDesktopState();
}
class _NavBarDesktopState extends State<NavBarDesktop> {
String authButtonTitle = "Войти";
@override
void initState() {
print('call init state navbar ${ApiClient.username}');
if (ApiClient.username != null && ApiClient.username.length > 0)
authButtonTitle = ApiClient.username;
super.initState();
}
void update() {
setState(() {
authButtonTitle = ApiClient.username;
});
}
@override
Widget build(BuildContext context) {
return new Container(
color: primaryColor,
height: 50,
padding: EdgeInsets.only(left: 50, right: 50),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
onTap: () {
LayoutTemplate.of(context).change_page(HomePageDesktop());
},
child: Text(
'UM',
textAlign: TextAlign.center,
style: TextStyle(
color: textPrimaryColor,
fontWeight: FontWeight.w600,
fontSize: 40),
)),
NavBarItem(
authButtonTitle,
() => LayoutTemplate.of(context)
.change_page(AuthorizationPageDesktop())),
],
),
);
}
void auth_page_up(BuildContext context) {
LayoutTemplate.of(context).change_page(AuthorizationPageDesktop());
}
}
例外
Error: setState() called in constructor: _NavBarDesktopState#5e1ee(lifecycle state: created, no widget, not mounted)
This happens when you call setState() on a State object for a widget that hasn't been inserted into the widget tree yet. It is not necessary to
call setState() in the constructor, since the state is already assumed to be dirty when it is initially created.
at Object.throw_ [as throw] (http://localhost:50572/dart_sdk.js:4334:11)
at http://localhost:50572/packages/flutter/src/widgets/widget_span.dart.lib.js:13615:23
at NavBarDesktop._NavBarDesktopState.new.setState (http://localhost:50572/packages/flutter/src/widgets/widget_span.dart.lib.js:13618:26)
at NavBarDesktop._NavBarDesktopState.new.update (http://localhost:50572/packages/um/scripts/router.dart.lib.js:1717:12)
at AuthPageDesktop._AuthorizationPageDesktopState.new.auth (http://localhost:50572/packages/um/scripts/router.dart.lib.js:1932:13)
at http://localhost:50572/packages/um/scripts/router.dart.lib.js:1926:15
at _RootZone.runUnary (http://localhost:50572/dart_sdk.js:37457:58)
at _FutureListener.then.handleValue (http://localhost:50572/dart_sdk.js:32441:29)
at handleValueCallback (http://localhost:50572/dart_sdk.js:32988:49)
at Function._propagateToListeners (http://localhost:50572/dart_sdk.js:33026:17)
at _Future.new.[_completeWithValue] (http://localhost:50572/dart_sdk.js:32869:23)
at async._AsyncCallbackEntry.new.callback (http://localhost:50572/dart_sdk.js:32891:35)
at Object._microtaskLoop (http://localhost:50572/dart_sdk.js:37718:13)
at _startMicrotaskLoop (http://localhost:50572/dart_sdk.js:37724:13)
at http://localhost:50572/dart_sdk.js:33243:9
【问题讨论】:
标签: flutter dart flutter-web