Я пытаюсь реализовать реактивный интерфейс для моего приложения. Я в начале, на экране входа в систему / регистрации, и у меня возникает проблема рендеринга, когда клавиатура показывает:
Performing hot reload...
Syncing files to device Android SDK built for x86...
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown building Container(constraints: BoxConstraints(0.0<=w<=Infinity, h=-15.0; NOT NORMALIZED), dirty):
BoxConstraints has a negative minimum height.
The offending constraints were: BoxConstraints(0.0<=w<=Infinity, h=-15.0; NOT NORMALIZED)
The relevant error-causing widget was:
Container file:///C:/Dev/mobile/lib/widgets/social_connectors.dart:40:17
When the exception was thrown, this was the stack:
#0 BoxConstraints.debugAssertIsValid.<anonymous closure>.throwError (package:flutter/src/rendering/box.dart:510:9)
#1 BoxConstraints.debugAssertIsValid.<anonymous closure> (package:flutter/src/rendering/box.dart:541:19)
#2 BoxConstraints.debugAssertIsValid (package:flutter/src/rendering/box.dart:558:6)
#3 new ConstrainedBox (package:flutter/src/widgets/basic.dart:2163:27)
#4 Container.build (package:flutter/src/widgets/container.dart:431:17)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
BoxConstraints has a negative minimum height.
The relevant error-causing widget was:
Container file:///C:/Dev/mobile/lib/widgets/social_connectors.dart:40:17
════════════════════════════════════════════════════════════════════════════════════════════════════
Reloaded 2 of 497 libraries in 363ms.
════════ Exception caught by rendering library ═════════════════════════════════════════════════════
The following assertion was thrown during layout:
A RenderFlex overflowed by 169 pixels on the bottom.
The relevant error-causing widget was:
Column file:///C:/Dev/mobile/lib/widgets/login_form.dart:21:22
The overflowing RenderFlex has an orientation of Axis.vertical.
The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and black striped pattern. This is usually caused by the contents being too big for the RenderFlex.
Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the RenderFlex to fit within the available space instead of being sized to their natural size.
This is considered an error condition because it indicates that there is content that cannot be seen. If the content is legitimately bigger than the available space, consider clipping it with a ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex, like a ListView.
The specific RenderFlex in question is: RenderFlex#4cdce OVERFLOWING
... needs compositing
... parentData: offset=Offset(0.0, 0.0) (can use size)
... constraints: BoxConstraints(w=324.0, h=23.0)
... size: Size(324.0, 23.0)
... direction: vertical
... mainAxisAlignment: center
... mainAxisSize: max
... crossAxisAlignment: center
... verticalDirection: down
◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤
════════════════════════════════════════════════════════════════════════════════════════════════════
W/IInputConnectionWrapper(12250): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(12250): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper(12250): getTextAfterCursor on inactive InputConnection
W/IInputConnectionWrapper(12250): beginBatchEdit on inactive InputConnection
W/IInputConnectionWrapper(12250): endBatchEdit on inactive InputConnection
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown building Container(constraints: BoxConstraints(0.0<=w<=Infinity, h=-15.0; NOT NORMALIZED), dirty):
BoxConstraints has a negative minimum height.
The offending constraints were: BoxConstraints(0.0<=w<=Infinity, h=-15.0; NOT NORMALIZED)
The relevant error-causing widget was:
Container file:///C:/Dev/mobile/lib/widgets/social_connectors.dart:40:17
When the exception was thrown, this was the stack:
#0 BoxConstraints.debugAssertIsValid.<anonymous closure>.throwError (package:flutter/src/rendering/box.dart:510:9)
#1 BoxConstraints.debugAssertIsValid.<anonymous closure> (package:flutter/src/rendering/box.dart:541:19)
#2 BoxConstraints.debugAssertIsValid (package:flutter/src/rendering/box.dart:558:6)
#3 new ConstrainedBox (package:flutter/src/widgets/basic.dart:2163:27)
#4 Container.build (package:flutter/src/widgets/container.dart:431:17)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
W/IInputConnectionWrapper(12250): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(12250): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper(12250): getTextAfterCursor on inactive InputConnection
W/IInputConnectionWrapper(12250): beginBatchEdit on inactive InputConnection
W/IInputConnectionWrapper(12250): endBatchEdit on inactive InputConnection
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown building Container(constraints: BoxConstraints(0.0<=w<=Infinity, h=-15.0; NOT NORMALIZED), dirty):
BoxConstraints has a negative minimum height.
The offending constraints were: BoxConstraints(0.0<=w<=Infinity, h=-15.0; NOT NORMALIZED)
The relevant error-causing widget was:
Container file:///C:/Dev/mobile/lib/widgets/social_connectors.dart:40:17
When the exception was thrown, this was the stack:
#0 BoxConstraints.debugAssertIsValid.<anonymous closure>.throwError (package:flutter/src/rendering/box.dart:510:9)
#1 BoxConstraints.debugAssertIsValid.<anonymous closure> (package:flutter/src/rendering/box.dart:541:19)
#2 BoxConstraints.debugAssertIsValid (package:flutter/src/rendering/box.dart:558:6)
#3 new ConstrainedBox (package:flutter/src/widgets/basic.dart:2163:27)
#4 Container.build (package:flutter/src/widgets/container.dart:431:17)
...
════════════════════════════════════════════════════════════════════════════════════════════════════
Вот мой макет:
class _AuthenticationPageState extends State<AuthenticationPage> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final authentication_vm = Provider.of<AuthenticationViewModel>(context);
SystemChrome.setEnabledSystemUIOverlays([]);
bool login_visible = true;
return Center(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/sheets.png"),
fit: BoxFit.fitHeight,
),
),
padding: EdgeInsets.fromLTRB(
MediaQuery.of(context).size.width * 0.05,
MediaQuery.of(context).size.height * 0.05,
MediaQuery.of(context).size.width * 0.05,
MediaQuery.of(context).size.height * 0.05),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height * 0.20,
child: LayoutBuilder(builder:
(BuildContext context, BoxConstraints constraints) {
return new Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
AnimatedOpacity(
opacity: login_visible ? 0.0 : 1.0,
duration: Duration(milliseconds: 500),
child: new Container(
height: constraints.maxHeight,
width: 30,
child: Container(
alignment: Alignment.topCenter,
child: new GestureDetector(
onTap: () {
Navigator.pop(context, true);
},
child: Icon(
Icons.arrow_back,
color: Colors.white,
),
),
),
),
),
new Image.asset(
"assets/logo.png",
height: constraints.maxHeight,
fit: BoxFit.fitHeight,
),
new Container(
width: 30,
),
],
);
}),
),
Container(
height: MediaQuery.of(context).size.height * 0.50,
child: ListView(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: false,
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width * 0.90,
height: MediaQuery.of(context).size.height * 0.50,
child: LoginForm(loginViewModel: authentication_vm),
),
Container(
width: MediaQuery.of(context).size.width * 0.90,
height: MediaQuery.of(context).size.height * 0.50,
child: RegisterForm(),
),
],
scrollDirection: Axis.horizontal,
),
),
Container(
alignment: Alignment.bottomCenter,
width: MediaQuery.of(context).size.width * 0.65,
height: MediaQuery.of(context).size.height * 0.20,
child: SocialConnectors()),
])),
),
);
}
}
с моим Класс формы входа в систему выглядит следующим образом:
class LoginForm extends StatelessWidget {
final AuthenticationViewModel loginViewModel;
final double spacer = 15.0;
LoginForm({this.loginViewModel});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Scaffold(
backgroundColor: Color(TRANSPARENT),
body: new FractionallySizedBox(
widthFactor: 1,
heightFactor: 1,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_showLoginInput(),
_showPasswordInput(),
new Container(
height: constraints.maxHeight * 0.05,
),
_showPrimaryButton(),
new Container(
height: constraints.maxHeight * 0.05,
),
Container(
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Text(
"Dont have an account? ",
style: TextStyle(color: Color(TEXT_COLOR)),
),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RegisterPage()));
},
child: Text(
" Register!",
style: TextStyle(color: Color(MAIN_COLOR)),
),
),
],
),
),
],
),
),
);
});
}
Widget _showLoginInput() {
return new TextFormField(
style: TextStyle(),
maxLines: 1,
keyboardType: TextInputType.text,
autofocus: false,
decoration: new InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(TEXT_COLOR)),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
hintText: 'Login',
hintStyle: TextStyle(color: Color(TEXT_COLOR)),
icon: new Icon(
Icons.account_circle,
color: Colors.white,
)),
);
}
Widget _showPasswordInput() {
return new TextFormField(
maxLines: 1,
obscureText: true,
autofocus: false,
decoration: new InputDecoration(
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Color(TEXT_COLOR)),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
hintText: 'Password',
hintStyle: TextStyle(color: Color(TEXT_COLOR)),
icon: new Icon(
Icons.lock,
color: Colors.white,
)),
);
}
Widget _showPrimaryButton() {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return new SizedBox(
width: constraints.maxWidth * 0.8,
child: new RaisedButton(
color: Color(MAIN_COLOR),
onPressed: () {},
textColor: Colors.white,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(10.0)),
child: Container(
child: const Text('Login', style: TextStyle(fontSize: 20)),
),
),
);
});
}
}
Моя цель состоит в том, чтобы иметь два состояния для рендеринга: показ логина или регистрации. При отображении одного или другого форма будет смахивать влево или вправо, а стрелка «go назад» будет отображать или скрывать.
Я попытался обернуть все в SingleChildScrollView, но это не работает , Как я могу сделать эту работу?