Flutter Layout with Fixed Bottom Section and Scrollable Upper SEction










0















I am currently writing a Flutter app for a kiosk-like device. This device will be mounted in landscape mode and has an integrated barcode scanner on the bottom.



The device will spend almost all of its time on a single layout:



Standard Layout w/o Keyboard



Currently, the entire body is in a SingleChildScrollView. This allows the view to 'slide up' when the user taps in text input box. Then when keyboard closes, the view 'slides' back down.



With Keyboard Active



What I'm trying to do is have the bottom "Scan Ticket Below" row to be fixed to the bottom of the view, at least when visible (when keyboard not covering it). As of now, it's a flex layout and it' doesn't quite get to the bottom.



Look at image with debug paint: the pink box should be at bottom, and everything above it should be in a scrollable view.
View with Debug Box Paint



I started messing around with a number of options. I don't want fixed positions as we will ultimately also make the solution available on iDevices with various screen sizes.



Here is my current Scaffold Body:



Container(
constraints: BoxConstraints.expand(),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: EdgeInsets.only(top: 50.0, bottom: 20.0),
child: Text(_message ?? "Welcome!",
textAlign: TextAlign.center,
style:
TextStyle(fontSize: 45.0, color: Colors.black)),
),
Padding(
padding: EdgeInsets.all(20.0),
child: Text("Scan ticket below or Search for your Transaction",
style:
TextStyle(fontSize: 25.0, color: Colors.black)),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
flex: 4,
child: Container(
margin: EdgeInsets.symmetric(
horizontal: 50.0, vertical: 25.0),
color: skidataThemeData.primaryColor,
padding: const EdgeInsets.symmetric(
horizontal: 25.0, vertical: 25.0),
child: Center(
child: new TextFormField(
//This autofocus works, but during transition from successful plate val to
//this page, the keyoard is activated during transition causing an overflow on the
//applyValidationScreen.
//autofocus: true,
style: new TextStyle(
decorationColor:
skidataThemeData.accentColor,
fontSize: 90.0,
color: skidataThemeData.accentColor),
textAlign: TextAlign.center,
onSaved: (String value)
this._data.plateNumber = value;
,
decoration: new InputDecoration(
hintText: "Enter Data",
hintStyle: new TextStyle(
color: Colors.white),
fillColor:
skidataThemeData.accentColor,
contentPadding: EdgeInsets.all(1.0),
border: InputBorder.none),
validator: (value)
if (value.isEmpty)
return 'Field cannot be blank.';

,
autocorrect: false,
),
))),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.all(25.0),
child: RaisedButton(
padding: EdgeInsets.all(15.0),
color: skidataThemeData.accentColor,
onPressed: () async
FocusScope.of(context)
.requestFocus(new FocusNode());
setState(()
_message = '';
);

if (_formKey.currentState.validate())
// If the form is valid, we want to show a Snackbar
Scaffold.of(context).showSnackBar(
new SnackBar(
content: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
new CircularProgressIndicator(
valueColor:
new AlwaysStoppedAnimation<
Color>(
skidataThemeData
.primaryColor),
),
Text(
'Search for matching record..',
style: new TextStyle(
color: skidataThemeData
.primaryColor))
],
),
backgroundColor:
skidataThemeData.accentColor,
duration: Duration(seconds: 10)),
);
await new Future.delayed(
const Duration(milliseconds: 1000));

Scaffold.of(context)
.hideCurrentSnackBar();

Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
new SvalKioskApp()),
);
else
setState(()
_message = "";
);

,
child: new Text('Search for Record',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25.0, color: Colors.black)),
),
))
]),
Container(
color: Colors.pink,
child: Padding(
padding: const EdgeInsets.only(top:40.0),
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(
horizontal: 10.0, vertical: 5.0),
child: Image.asset(
'images/downarrow.png',
fit: BoxFit.contain,
),
)),
Expanded(
flex: 5,
child: Center(
child: Text("Scan Physical Ticket Below!",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 45.0)))),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.symmetric(
horizontal: 10.0, vertical: 5.0),
child: Image.asset(
'images/downarrow.png',
fit: BoxFit.contain,
),
)),
]),
),
)
]),
),
)









share|improve this question

















  • 1





    you can use a stack widget to accomplish that

    – nonybrighto
    Nov 16 '18 at 1:39











  • This is something I did try. I created stack with the scrollable widget positioned at top and the fixed bottom widget at bottom. However, when the keyboard opened, the fixed bottom widget then moved to be fixed to the bottom of viewport, which was then above the keyboard. If I set resizeToAvoidBottomPadding on the Saffold to false, the fixed bottom widget wouldn't show at all.

    – Jeffrey
    Nov 16 '18 at 18:28
















0















I am currently writing a Flutter app for a kiosk-like device. This device will be mounted in landscape mode and has an integrated barcode scanner on the bottom.



The device will spend almost all of its time on a single layout:



Standard Layout w/o Keyboard



Currently, the entire body is in a SingleChildScrollView. This allows the view to 'slide up' when the user taps in text input box. Then when keyboard closes, the view 'slides' back down.



With Keyboard Active



What I'm trying to do is have the bottom "Scan Ticket Below" row to be fixed to the bottom of the view, at least when visible (when keyboard not covering it). As of now, it's a flex layout and it' doesn't quite get to the bottom.



Look at image with debug paint: the pink box should be at bottom, and everything above it should be in a scrollable view.
View with Debug Box Paint



I started messing around with a number of options. I don't want fixed positions as we will ultimately also make the solution available on iDevices with various screen sizes.



Here is my current Scaffold Body:



Container(
constraints: BoxConstraints.expand(),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: EdgeInsets.only(top: 50.0, bottom: 20.0),
child: Text(_message ?? "Welcome!",
textAlign: TextAlign.center,
style:
TextStyle(fontSize: 45.0, color: Colors.black)),
),
Padding(
padding: EdgeInsets.all(20.0),
child: Text("Scan ticket below or Search for your Transaction",
style:
TextStyle(fontSize: 25.0, color: Colors.black)),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
flex: 4,
child: Container(
margin: EdgeInsets.symmetric(
horizontal: 50.0, vertical: 25.0),
color: skidataThemeData.primaryColor,
padding: const EdgeInsets.symmetric(
horizontal: 25.0, vertical: 25.0),
child: Center(
child: new TextFormField(
//This autofocus works, but during transition from successful plate val to
//this page, the keyoard is activated during transition causing an overflow on the
//applyValidationScreen.
//autofocus: true,
style: new TextStyle(
decorationColor:
skidataThemeData.accentColor,
fontSize: 90.0,
color: skidataThemeData.accentColor),
textAlign: TextAlign.center,
onSaved: (String value)
this._data.plateNumber = value;
,
decoration: new InputDecoration(
hintText: "Enter Data",
hintStyle: new TextStyle(
color: Colors.white),
fillColor:
skidataThemeData.accentColor,
contentPadding: EdgeInsets.all(1.0),
border: InputBorder.none),
validator: (value)
if (value.isEmpty)
return 'Field cannot be blank.';

,
autocorrect: false,
),
))),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.all(25.0),
child: RaisedButton(
padding: EdgeInsets.all(15.0),
color: skidataThemeData.accentColor,
onPressed: () async
FocusScope.of(context)
.requestFocus(new FocusNode());
setState(()
_message = '';
);

if (_formKey.currentState.validate())
// If the form is valid, we want to show a Snackbar
Scaffold.of(context).showSnackBar(
new SnackBar(
content: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
new CircularProgressIndicator(
valueColor:
new AlwaysStoppedAnimation<
Color>(
skidataThemeData
.primaryColor),
),
Text(
'Search for matching record..',
style: new TextStyle(
color: skidataThemeData
.primaryColor))
],
),
backgroundColor:
skidataThemeData.accentColor,
duration: Duration(seconds: 10)),
);
await new Future.delayed(
const Duration(milliseconds: 1000));

Scaffold.of(context)
.hideCurrentSnackBar();

Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
new SvalKioskApp()),
);
else
setState(()
_message = "";
);

,
child: new Text('Search for Record',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25.0, color: Colors.black)),
),
))
]),
Container(
color: Colors.pink,
child: Padding(
padding: const EdgeInsets.only(top:40.0),
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(
horizontal: 10.0, vertical: 5.0),
child: Image.asset(
'images/downarrow.png',
fit: BoxFit.contain,
),
)),
Expanded(
flex: 5,
child: Center(
child: Text("Scan Physical Ticket Below!",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 45.0)))),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.symmetric(
horizontal: 10.0, vertical: 5.0),
child: Image.asset(
'images/downarrow.png',
fit: BoxFit.contain,
),
)),
]),
),
)
]),
),
)









share|improve this question

















  • 1





    you can use a stack widget to accomplish that

    – nonybrighto
    Nov 16 '18 at 1:39











  • This is something I did try. I created stack with the scrollable widget positioned at top and the fixed bottom widget at bottom. However, when the keyboard opened, the fixed bottom widget then moved to be fixed to the bottom of viewport, which was then above the keyboard. If I set resizeToAvoidBottomPadding on the Saffold to false, the fixed bottom widget wouldn't show at all.

    – Jeffrey
    Nov 16 '18 at 18:28














0












0








0








I am currently writing a Flutter app for a kiosk-like device. This device will be mounted in landscape mode and has an integrated barcode scanner on the bottom.



The device will spend almost all of its time on a single layout:



Standard Layout w/o Keyboard



Currently, the entire body is in a SingleChildScrollView. This allows the view to 'slide up' when the user taps in text input box. Then when keyboard closes, the view 'slides' back down.



With Keyboard Active



What I'm trying to do is have the bottom "Scan Ticket Below" row to be fixed to the bottom of the view, at least when visible (when keyboard not covering it). As of now, it's a flex layout and it' doesn't quite get to the bottom.



Look at image with debug paint: the pink box should be at bottom, and everything above it should be in a scrollable view.
View with Debug Box Paint



I started messing around with a number of options. I don't want fixed positions as we will ultimately also make the solution available on iDevices with various screen sizes.



Here is my current Scaffold Body:



Container(
constraints: BoxConstraints.expand(),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: EdgeInsets.only(top: 50.0, bottom: 20.0),
child: Text(_message ?? "Welcome!",
textAlign: TextAlign.center,
style:
TextStyle(fontSize: 45.0, color: Colors.black)),
),
Padding(
padding: EdgeInsets.all(20.0),
child: Text("Scan ticket below or Search for your Transaction",
style:
TextStyle(fontSize: 25.0, color: Colors.black)),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
flex: 4,
child: Container(
margin: EdgeInsets.symmetric(
horizontal: 50.0, vertical: 25.0),
color: skidataThemeData.primaryColor,
padding: const EdgeInsets.symmetric(
horizontal: 25.0, vertical: 25.0),
child: Center(
child: new TextFormField(
//This autofocus works, but during transition from successful plate val to
//this page, the keyoard is activated during transition causing an overflow on the
//applyValidationScreen.
//autofocus: true,
style: new TextStyle(
decorationColor:
skidataThemeData.accentColor,
fontSize: 90.0,
color: skidataThemeData.accentColor),
textAlign: TextAlign.center,
onSaved: (String value)
this._data.plateNumber = value;
,
decoration: new InputDecoration(
hintText: "Enter Data",
hintStyle: new TextStyle(
color: Colors.white),
fillColor:
skidataThemeData.accentColor,
contentPadding: EdgeInsets.all(1.0),
border: InputBorder.none),
validator: (value)
if (value.isEmpty)
return 'Field cannot be blank.';

,
autocorrect: false,
),
))),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.all(25.0),
child: RaisedButton(
padding: EdgeInsets.all(15.0),
color: skidataThemeData.accentColor,
onPressed: () async
FocusScope.of(context)
.requestFocus(new FocusNode());
setState(()
_message = '';
);

if (_formKey.currentState.validate())
// If the form is valid, we want to show a Snackbar
Scaffold.of(context).showSnackBar(
new SnackBar(
content: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
new CircularProgressIndicator(
valueColor:
new AlwaysStoppedAnimation<
Color>(
skidataThemeData
.primaryColor),
),
Text(
'Search for matching record..',
style: new TextStyle(
color: skidataThemeData
.primaryColor))
],
),
backgroundColor:
skidataThemeData.accentColor,
duration: Duration(seconds: 10)),
);
await new Future.delayed(
const Duration(milliseconds: 1000));

Scaffold.of(context)
.hideCurrentSnackBar();

Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
new SvalKioskApp()),
);
else
setState(()
_message = "";
);

,
child: new Text('Search for Record',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25.0, color: Colors.black)),
),
))
]),
Container(
color: Colors.pink,
child: Padding(
padding: const EdgeInsets.only(top:40.0),
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(
horizontal: 10.0, vertical: 5.0),
child: Image.asset(
'images/downarrow.png',
fit: BoxFit.contain,
),
)),
Expanded(
flex: 5,
child: Center(
child: Text("Scan Physical Ticket Below!",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 45.0)))),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.symmetric(
horizontal: 10.0, vertical: 5.0),
child: Image.asset(
'images/downarrow.png',
fit: BoxFit.contain,
),
)),
]),
),
)
]),
),
)









share|improve this question














I am currently writing a Flutter app for a kiosk-like device. This device will be mounted in landscape mode and has an integrated barcode scanner on the bottom.



The device will spend almost all of its time on a single layout:



Standard Layout w/o Keyboard



Currently, the entire body is in a SingleChildScrollView. This allows the view to 'slide up' when the user taps in text input box. Then when keyboard closes, the view 'slides' back down.



With Keyboard Active



What I'm trying to do is have the bottom "Scan Ticket Below" row to be fixed to the bottom of the view, at least when visible (when keyboard not covering it). As of now, it's a flex layout and it' doesn't quite get to the bottom.



Look at image with debug paint: the pink box should be at bottom, and everything above it should be in a scrollable view.
View with Debug Box Paint



I started messing around with a number of options. I don't want fixed positions as we will ultimately also make the solution available on iDevices with various screen sizes.



Here is my current Scaffold Body:



Container(
constraints: BoxConstraints.expand(),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: EdgeInsets.only(top: 50.0, bottom: 20.0),
child: Text(_message ?? "Welcome!",
textAlign: TextAlign.center,
style:
TextStyle(fontSize: 45.0, color: Colors.black)),
),
Padding(
padding: EdgeInsets.all(20.0),
child: Text("Scan ticket below or Search for your Transaction",
style:
TextStyle(fontSize: 25.0, color: Colors.black)),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
flex: 4,
child: Container(
margin: EdgeInsets.symmetric(
horizontal: 50.0, vertical: 25.0),
color: skidataThemeData.primaryColor,
padding: const EdgeInsets.symmetric(
horizontal: 25.0, vertical: 25.0),
child: Center(
child: new TextFormField(
//This autofocus works, but during transition from successful plate val to
//this page, the keyoard is activated during transition causing an overflow on the
//applyValidationScreen.
//autofocus: true,
style: new TextStyle(
decorationColor:
skidataThemeData.accentColor,
fontSize: 90.0,
color: skidataThemeData.accentColor),
textAlign: TextAlign.center,
onSaved: (String value)
this._data.plateNumber = value;
,
decoration: new InputDecoration(
hintText: "Enter Data",
hintStyle: new TextStyle(
color: Colors.white),
fillColor:
skidataThemeData.accentColor,
contentPadding: EdgeInsets.all(1.0),
border: InputBorder.none),
validator: (value)
if (value.isEmpty)
return 'Field cannot be blank.';

,
autocorrect: false,
),
))),
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsets.all(25.0),
child: RaisedButton(
padding: EdgeInsets.all(15.0),
color: skidataThemeData.accentColor,
onPressed: () async
FocusScope.of(context)
.requestFocus(new FocusNode());
setState(()
_message = '';
);

if (_formKey.currentState.validate())
// If the form is valid, we want to show a Snackbar
Scaffold.of(context).showSnackBar(
new SnackBar(
content: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
new CircularProgressIndicator(
valueColor:
new AlwaysStoppedAnimation<
Color>(
skidataThemeData
.primaryColor),
),
Text(
'Search for matching record..',
style: new TextStyle(
color: skidataThemeData
.primaryColor))
],
),
backgroundColor:
skidataThemeData.accentColor,
duration: Duration(seconds: 10)),
);
await new Future.delayed(
const Duration(milliseconds: 1000));

Scaffold.of(context)
.hideCurrentSnackBar();

Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
new SvalKioskApp()),
);
else
setState(()
_message = "";
);

,
child: new Text('Search for Record',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 25.0, color: Colors.black)),
),
))
]),
Container(
color: Colors.pink,
child: Padding(
padding: const EdgeInsets.only(top:40.0),
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(
horizontal: 10.0, vertical: 5.0),
child: Image.asset(
'images/downarrow.png',
fit: BoxFit.contain,
),
)),
Expanded(
flex: 5,
child: Center(
child: Text("Scan Physical Ticket Below!",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 45.0)))),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.symmetric(
horizontal: 10.0, vertical: 5.0),
child: Image.asset(
'images/downarrow.png',
fit: BoxFit.contain,
),
)),
]),
),
)
]),
),
)






flutter flutter-layout






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 15 '18 at 23:36









JeffreyJeffrey

3816




3816







  • 1





    you can use a stack widget to accomplish that

    – nonybrighto
    Nov 16 '18 at 1:39











  • This is something I did try. I created stack with the scrollable widget positioned at top and the fixed bottom widget at bottom. However, when the keyboard opened, the fixed bottom widget then moved to be fixed to the bottom of viewport, which was then above the keyboard. If I set resizeToAvoidBottomPadding on the Saffold to false, the fixed bottom widget wouldn't show at all.

    – Jeffrey
    Nov 16 '18 at 18:28













  • 1





    you can use a stack widget to accomplish that

    – nonybrighto
    Nov 16 '18 at 1:39











  • This is something I did try. I created stack with the scrollable widget positioned at top and the fixed bottom widget at bottom. However, when the keyboard opened, the fixed bottom widget then moved to be fixed to the bottom of viewport, which was then above the keyboard. If I set resizeToAvoidBottomPadding on the Saffold to false, the fixed bottom widget wouldn't show at all.

    – Jeffrey
    Nov 16 '18 at 18:28








1




1





you can use a stack widget to accomplish that

– nonybrighto
Nov 16 '18 at 1:39





you can use a stack widget to accomplish that

– nonybrighto
Nov 16 '18 at 1:39













This is something I did try. I created stack with the scrollable widget positioned at top and the fixed bottom widget at bottom. However, when the keyboard opened, the fixed bottom widget then moved to be fixed to the bottom of viewport, which was then above the keyboard. If I set resizeToAvoidBottomPadding on the Saffold to false, the fixed bottom widget wouldn't show at all.

– Jeffrey
Nov 16 '18 at 18:28






This is something I did try. I created stack with the scrollable widget positioned at top and the fixed bottom widget at bottom. However, when the keyboard opened, the fixed bottom widget then moved to be fixed to the bottom of viewport, which was then above the keyboard. If I set resizeToAvoidBottomPadding on the Saffold to false, the fixed bottom widget wouldn't show at all.

– Jeffrey
Nov 16 '18 at 18:28













2 Answers
2






active

oldest

votes


















0














The solution hit me when I was in the shower this morning:



Start with a column that you break into two Expanded widgets to get the top/bottom section ration desired.



Then in each Expanded, make a child container expanded to fill space. In the top container, set alignment to topCenter and set bottom container alignment to bottomCenter



In the top container, add a SingleChildScrollView child. Now the upper section is scrollable and bottom is fixed.



 Widget getInputView() {
return Builder(
builder: (context) => Container(
constraints: BoxConstraints.expand(),
child: Column(
children: <Widget>[
Expanded(
flex: 4,
child: Container(
alignment: Alignment.topCenter,
constraints: BoxConstraints.expand(),
child: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.end,
mainAxisSize: MainAxisSize.max,
children: [
Text("$_kiosk.kioskName",
textAlign: TextAlign.end)
]),
),
Padding(
padding: EdgeInsets.symmetric(vertical:30.0),
child: Text(
_kiosk.displayMessage ?? "Welcome!",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 45.0,
color: Colors.black)),
),
Padding(
padding: EdgeInsets.all(20.0),
child: Text(
"Scan barcode below or enter search data in box.",
style: TextStyle(
fontSize: 25.0,
color: Colors.black)),
),
Row(
mainAxisAlignment:
MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
flex: 4,
child: Container(
margin: EdgeInsets.symmetric(
horizontal: 50.0,
vertical: 25.0),
color: themeData
.primaryColor,
padding: const EdgeInsets
.symmetric(
horizontal: 25.0,
vertical: 25.0),
child: Center(
child: new TextFormField(
//This autofocus works, but during transition from successful plate val to
//this page, the keyoard is activated during transition causing an overflow on the
//applyValidationScreen.
//autofocus: true,
style: new TextStyle(
decorationColor:
themeData
.accentColor,
fontSize: 90.0,
color:
themeData
.accentColor),
textAlign:
TextAlign.center,
onSaved: (String value)
this._data.plateNumber =
value;
,
decoration: new InputDecoration(
hintText:
"Enter Data",
hintStyle:
new TextStyle(
color: Colors
.white),
fillColor:
themeData
.accentColor,
contentPadding:
EdgeInsets.all(
1.0),
border:
InputBorder.none),
validator: (value)
if (value.isEmpty)
return 'Field cannot be blank.';

,
autocorrect: false,
),
))),
Expanded(
flex: 1,
child: Padding(
padding:
const EdgeInsets.all(25.0),
child: RaisedButton(
padding: EdgeInsets.all(15.0),
color: themeData
.accentColor,
onPressed: () async
FocusScope.of(context)
.requestFocus(
new FocusNode());

if (_formKey.currentState
.validate())
// If the form is valid, we want to show a Snackbar
Scaffold.of(context)
.showSnackBar(
new SnackBar(
content: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
new CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<
Color>(
themeData
.primaryColor),
),
Text(
'Search for matching ticket..',
style: new TextStyle(
color: themeData
.primaryColor))
],
),
backgroundColor:
themeData
.accentColor,
duration: Duration(
seconds: 10)),
);
await new Future.delayed(
const Duration(
milliseconds:
1000));
PlateMatchResponse resp =
await this.submit();

Scaffold.of(context)
.hideCurrentSnackBar();

Navigator.push(
context,
new MaterialPageRoute(
builder: (context) =>
new SvalKioskApp()),
);

,
child: new Text(
'Search for Data Match',
textAlign:
TextAlign.center,
style: TextStyle(
fontSize: 25.0,
color: Colors.black)),
),
))
]),
]),
),
))),
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.all(25.0),
alignment: Alignment.bottomCenter,
constraints: BoxConstraints.expand(),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(
horizontal: 10.0, vertical: 5.0),
child: Image.asset(
'images/downarrow.png',
fit: BoxFit.contain,
),
)),
Expanded(
flex: 5,
child: Center(
child: Text(
"Scan Physical Ticket Below",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 45.0)))),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.symmetric(
horizontal: 10.0, vertical: 5.0),
child: Image.asset(
'images/downarrow.png',
fit: BoxFit.contain,
),
)),
])))
],
),
));





share|improve this answer






























    0














    How about replacing the SingleChildScrollView with a Column and then setting the resizeToAvoidBottomPadding property of the Scaffold to false so you don't need the scrollview, since the keyboard will not force the layout to resize.






    share|improve this answer























    • I did start with this. In this case, the keyboard would then cover part of the view, including part of the input box as it is closer to the center of screen and the layout is landscape. However, if the input box was placed above the location where the keyboard would display, this would work.

      – Jeffrey
      Nov 21 '18 at 15:59










    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53329366%2fflutter-layout-with-fixed-bottom-section-and-scrollable-upper-section%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    The solution hit me when I was in the shower this morning:



    Start with a column that you break into two Expanded widgets to get the top/bottom section ration desired.



    Then in each Expanded, make a child container expanded to fill space. In the top container, set alignment to topCenter and set bottom container alignment to bottomCenter



    In the top container, add a SingleChildScrollView child. Now the upper section is scrollable and bottom is fixed.



     Widget getInputView() {
    return Builder(
    builder: (context) => Container(
    constraints: BoxConstraints.expand(),
    child: Column(
    children: <Widget>[
    Expanded(
    flex: 4,
    child: Container(
    alignment: Alignment.topCenter,
    constraints: BoxConstraints.expand(),
    child: SingleChildScrollView(
    child: Form(
    key: _formKey,
    child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    mainAxisSize: MainAxisSize.min,
    children: [
    Padding(
    padding: const EdgeInsets.all(10.0),
    child: Row(
    mainAxisAlignment:
    MainAxisAlignment.end,
    mainAxisSize: MainAxisSize.max,
    children: [
    Text("$_kiosk.kioskName",
    textAlign: TextAlign.end)
    ]),
    ),
    Padding(
    padding: EdgeInsets.symmetric(vertical:30.0),
    child: Text(
    _kiosk.displayMessage ?? "Welcome!",
    textAlign: TextAlign.center,
    style: TextStyle(
    fontSize: 45.0,
    color: Colors.black)),
    ),
    Padding(
    padding: EdgeInsets.all(20.0),
    child: Text(
    "Scan barcode below or enter search data in box.",
    style: TextStyle(
    fontSize: 25.0,
    color: Colors.black)),
    ),
    Row(
    mainAxisAlignment:
    MainAxisAlignment.center,
    mainAxisSize: MainAxisSize.max,
    children: [
    Expanded(
    flex: 4,
    child: Container(
    margin: EdgeInsets.symmetric(
    horizontal: 50.0,
    vertical: 25.0),
    color: themeData
    .primaryColor,
    padding: const EdgeInsets
    .symmetric(
    horizontal: 25.0,
    vertical: 25.0),
    child: Center(
    child: new TextFormField(
    //This autofocus works, but during transition from successful plate val to
    //this page, the keyoard is activated during transition causing an overflow on the
    //applyValidationScreen.
    //autofocus: true,
    style: new TextStyle(
    decorationColor:
    themeData
    .accentColor,
    fontSize: 90.0,
    color:
    themeData
    .accentColor),
    textAlign:
    TextAlign.center,
    onSaved: (String value)
    this._data.plateNumber =
    value;
    ,
    decoration: new InputDecoration(
    hintText:
    "Enter Data",
    hintStyle:
    new TextStyle(
    color: Colors
    .white),
    fillColor:
    themeData
    .accentColor,
    contentPadding:
    EdgeInsets.all(
    1.0),
    border:
    InputBorder.none),
    validator: (value)
    if (value.isEmpty)
    return 'Field cannot be blank.';

    ,
    autocorrect: false,
    ),
    ))),
    Expanded(
    flex: 1,
    child: Padding(
    padding:
    const EdgeInsets.all(25.0),
    child: RaisedButton(
    padding: EdgeInsets.all(15.0),
    color: themeData
    .accentColor,
    onPressed: () async
    FocusScope.of(context)
    .requestFocus(
    new FocusNode());

    if (_formKey.currentState
    .validate())
    // If the form is valid, we want to show a Snackbar
    Scaffold.of(context)
    .showSnackBar(
    new SnackBar(
    content: Row(
    mainAxisAlignment:
    MainAxisAlignment
    .spaceBetween,
    children: [
    new CircularProgressIndicator(
    valueColor: new AlwaysStoppedAnimation<
    Color>(
    themeData
    .primaryColor),
    ),
    Text(
    'Search for matching ticket..',
    style: new TextStyle(
    color: themeData
    .primaryColor))
    ],
    ),
    backgroundColor:
    themeData
    .accentColor,
    duration: Duration(
    seconds: 10)),
    );
    await new Future.delayed(
    const Duration(
    milliseconds:
    1000));
    PlateMatchResponse resp =
    await this.submit();

    Scaffold.of(context)
    .hideCurrentSnackBar();

    Navigator.push(
    context,
    new MaterialPageRoute(
    builder: (context) =>
    new SvalKioskApp()),
    );

    ,
    child: new Text(
    'Search for Data Match',
    textAlign:
    TextAlign.center,
    style: TextStyle(
    fontSize: 25.0,
    color: Colors.black)),
    ),
    ))
    ]),
    ]),
    ),
    ))),
    Expanded(
    flex: 1,
    child: Container(
    padding: EdgeInsets.all(25.0),
    alignment: Alignment.bottomCenter,
    constraints: BoxConstraints.expand(),
    child: Row(
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
    Expanded(
    flex: 1,
    child: Container(
    alignment: Alignment.centerRight,
    padding: EdgeInsets.symmetric(
    horizontal: 10.0, vertical: 5.0),
    child: Image.asset(
    'images/downarrow.png',
    fit: BoxFit.contain,
    ),
    )),
    Expanded(
    flex: 5,
    child: Center(
    child: Text(
    "Scan Physical Ticket Below",
    style: TextStyle(
    fontWeight: FontWeight.bold,
    fontSize: 45.0)))),
    Expanded(
    flex: 1,
    child: Container(
    alignment: Alignment.centerLeft,
    padding: EdgeInsets.symmetric(
    horizontal: 10.0, vertical: 5.0),
    child: Image.asset(
    'images/downarrow.png',
    fit: BoxFit.contain,
    ),
    )),
    ])))
    ],
    ),
    ));





    share|improve this answer



























      0














      The solution hit me when I was in the shower this morning:



      Start with a column that you break into two Expanded widgets to get the top/bottom section ration desired.



      Then in each Expanded, make a child container expanded to fill space. In the top container, set alignment to topCenter and set bottom container alignment to bottomCenter



      In the top container, add a SingleChildScrollView child. Now the upper section is scrollable and bottom is fixed.



       Widget getInputView() {
      return Builder(
      builder: (context) => Container(
      constraints: BoxConstraints.expand(),
      child: Column(
      children: <Widget>[
      Expanded(
      flex: 4,
      child: Container(
      alignment: Alignment.topCenter,
      constraints: BoxConstraints.expand(),
      child: SingleChildScrollView(
      child: Form(
      key: _formKey,
      child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      mainAxisSize: MainAxisSize.min,
      children: [
      Padding(
      padding: const EdgeInsets.all(10.0),
      child: Row(
      mainAxisAlignment:
      MainAxisAlignment.end,
      mainAxisSize: MainAxisSize.max,
      children: [
      Text("$_kiosk.kioskName",
      textAlign: TextAlign.end)
      ]),
      ),
      Padding(
      padding: EdgeInsets.symmetric(vertical:30.0),
      child: Text(
      _kiosk.displayMessage ?? "Welcome!",
      textAlign: TextAlign.center,
      style: TextStyle(
      fontSize: 45.0,
      color: Colors.black)),
      ),
      Padding(
      padding: EdgeInsets.all(20.0),
      child: Text(
      "Scan barcode below or enter search data in box.",
      style: TextStyle(
      fontSize: 25.0,
      color: Colors.black)),
      ),
      Row(
      mainAxisAlignment:
      MainAxisAlignment.center,
      mainAxisSize: MainAxisSize.max,
      children: [
      Expanded(
      flex: 4,
      child: Container(
      margin: EdgeInsets.symmetric(
      horizontal: 50.0,
      vertical: 25.0),
      color: themeData
      .primaryColor,
      padding: const EdgeInsets
      .symmetric(
      horizontal: 25.0,
      vertical: 25.0),
      child: Center(
      child: new TextFormField(
      //This autofocus works, but during transition from successful plate val to
      //this page, the keyoard is activated during transition causing an overflow on the
      //applyValidationScreen.
      //autofocus: true,
      style: new TextStyle(
      decorationColor:
      themeData
      .accentColor,
      fontSize: 90.0,
      color:
      themeData
      .accentColor),
      textAlign:
      TextAlign.center,
      onSaved: (String value)
      this._data.plateNumber =
      value;
      ,
      decoration: new InputDecoration(
      hintText:
      "Enter Data",
      hintStyle:
      new TextStyle(
      color: Colors
      .white),
      fillColor:
      themeData
      .accentColor,
      contentPadding:
      EdgeInsets.all(
      1.0),
      border:
      InputBorder.none),
      validator: (value)
      if (value.isEmpty)
      return 'Field cannot be blank.';

      ,
      autocorrect: false,
      ),
      ))),
      Expanded(
      flex: 1,
      child: Padding(
      padding:
      const EdgeInsets.all(25.0),
      child: RaisedButton(
      padding: EdgeInsets.all(15.0),
      color: themeData
      .accentColor,
      onPressed: () async
      FocusScope.of(context)
      .requestFocus(
      new FocusNode());

      if (_formKey.currentState
      .validate())
      // If the form is valid, we want to show a Snackbar
      Scaffold.of(context)
      .showSnackBar(
      new SnackBar(
      content: Row(
      mainAxisAlignment:
      MainAxisAlignment
      .spaceBetween,
      children: [
      new CircularProgressIndicator(
      valueColor: new AlwaysStoppedAnimation<
      Color>(
      themeData
      .primaryColor),
      ),
      Text(
      'Search for matching ticket..',
      style: new TextStyle(
      color: themeData
      .primaryColor))
      ],
      ),
      backgroundColor:
      themeData
      .accentColor,
      duration: Duration(
      seconds: 10)),
      );
      await new Future.delayed(
      const Duration(
      milliseconds:
      1000));
      PlateMatchResponse resp =
      await this.submit();

      Scaffold.of(context)
      .hideCurrentSnackBar();

      Navigator.push(
      context,
      new MaterialPageRoute(
      builder: (context) =>
      new SvalKioskApp()),
      );

      ,
      child: new Text(
      'Search for Data Match',
      textAlign:
      TextAlign.center,
      style: TextStyle(
      fontSize: 25.0,
      color: Colors.black)),
      ),
      ))
      ]),
      ]),
      ),
      ))),
      Expanded(
      flex: 1,
      child: Container(
      padding: EdgeInsets.all(25.0),
      alignment: Alignment.bottomCenter,
      constraints: BoxConstraints.expand(),
      child: Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
      Expanded(
      flex: 1,
      child: Container(
      alignment: Alignment.centerRight,
      padding: EdgeInsets.symmetric(
      horizontal: 10.0, vertical: 5.0),
      child: Image.asset(
      'images/downarrow.png',
      fit: BoxFit.contain,
      ),
      )),
      Expanded(
      flex: 5,
      child: Center(
      child: Text(
      "Scan Physical Ticket Below",
      style: TextStyle(
      fontWeight: FontWeight.bold,
      fontSize: 45.0)))),
      Expanded(
      flex: 1,
      child: Container(
      alignment: Alignment.centerLeft,
      padding: EdgeInsets.symmetric(
      horizontal: 10.0, vertical: 5.0),
      child: Image.asset(
      'images/downarrow.png',
      fit: BoxFit.contain,
      ),
      )),
      ])))
      ],
      ),
      ));





      share|improve this answer

























        0












        0








        0







        The solution hit me when I was in the shower this morning:



        Start with a column that you break into two Expanded widgets to get the top/bottom section ration desired.



        Then in each Expanded, make a child container expanded to fill space. In the top container, set alignment to topCenter and set bottom container alignment to bottomCenter



        In the top container, add a SingleChildScrollView child. Now the upper section is scrollable and bottom is fixed.



         Widget getInputView() {
        return Builder(
        builder: (context) => Container(
        constraints: BoxConstraints.expand(),
        child: Column(
        children: <Widget>[
        Expanded(
        flex: 4,
        child: Container(
        alignment: Alignment.topCenter,
        constraints: BoxConstraints.expand(),
        child: SingleChildScrollView(
        child: Form(
        key: _formKey,
        child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: [
        Padding(
        padding: const EdgeInsets.all(10.0),
        child: Row(
        mainAxisAlignment:
        MainAxisAlignment.end,
        mainAxisSize: MainAxisSize.max,
        children: [
        Text("$_kiosk.kioskName",
        textAlign: TextAlign.end)
        ]),
        ),
        Padding(
        padding: EdgeInsets.symmetric(vertical:30.0),
        child: Text(
        _kiosk.displayMessage ?? "Welcome!",
        textAlign: TextAlign.center,
        style: TextStyle(
        fontSize: 45.0,
        color: Colors.black)),
        ),
        Padding(
        padding: EdgeInsets.all(20.0),
        child: Text(
        "Scan barcode below or enter search data in box.",
        style: TextStyle(
        fontSize: 25.0,
        color: Colors.black)),
        ),
        Row(
        mainAxisAlignment:
        MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.max,
        children: [
        Expanded(
        flex: 4,
        child: Container(
        margin: EdgeInsets.symmetric(
        horizontal: 50.0,
        vertical: 25.0),
        color: themeData
        .primaryColor,
        padding: const EdgeInsets
        .symmetric(
        horizontal: 25.0,
        vertical: 25.0),
        child: Center(
        child: new TextFormField(
        //This autofocus works, but during transition from successful plate val to
        //this page, the keyoard is activated during transition causing an overflow on the
        //applyValidationScreen.
        //autofocus: true,
        style: new TextStyle(
        decorationColor:
        themeData
        .accentColor,
        fontSize: 90.0,
        color:
        themeData
        .accentColor),
        textAlign:
        TextAlign.center,
        onSaved: (String value)
        this._data.plateNumber =
        value;
        ,
        decoration: new InputDecoration(
        hintText:
        "Enter Data",
        hintStyle:
        new TextStyle(
        color: Colors
        .white),
        fillColor:
        themeData
        .accentColor,
        contentPadding:
        EdgeInsets.all(
        1.0),
        border:
        InputBorder.none),
        validator: (value)
        if (value.isEmpty)
        return 'Field cannot be blank.';

        ,
        autocorrect: false,
        ),
        ))),
        Expanded(
        flex: 1,
        child: Padding(
        padding:
        const EdgeInsets.all(25.0),
        child: RaisedButton(
        padding: EdgeInsets.all(15.0),
        color: themeData
        .accentColor,
        onPressed: () async
        FocusScope.of(context)
        .requestFocus(
        new FocusNode());

        if (_formKey.currentState
        .validate())
        // If the form is valid, we want to show a Snackbar
        Scaffold.of(context)
        .showSnackBar(
        new SnackBar(
        content: Row(
        mainAxisAlignment:
        MainAxisAlignment
        .spaceBetween,
        children: [
        new CircularProgressIndicator(
        valueColor: new AlwaysStoppedAnimation<
        Color>(
        themeData
        .primaryColor),
        ),
        Text(
        'Search for matching ticket..',
        style: new TextStyle(
        color: themeData
        .primaryColor))
        ],
        ),
        backgroundColor:
        themeData
        .accentColor,
        duration: Duration(
        seconds: 10)),
        );
        await new Future.delayed(
        const Duration(
        milliseconds:
        1000));
        PlateMatchResponse resp =
        await this.submit();

        Scaffold.of(context)
        .hideCurrentSnackBar();

        Navigator.push(
        context,
        new MaterialPageRoute(
        builder: (context) =>
        new SvalKioskApp()),
        );

        ,
        child: new Text(
        'Search for Data Match',
        textAlign:
        TextAlign.center,
        style: TextStyle(
        fontSize: 25.0,
        color: Colors.black)),
        ),
        ))
        ]),
        ]),
        ),
        ))),
        Expanded(
        flex: 1,
        child: Container(
        padding: EdgeInsets.all(25.0),
        alignment: Alignment.bottomCenter,
        constraints: BoxConstraints.expand(),
        child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
        Expanded(
        flex: 1,
        child: Container(
        alignment: Alignment.centerRight,
        padding: EdgeInsets.symmetric(
        horizontal: 10.0, vertical: 5.0),
        child: Image.asset(
        'images/downarrow.png',
        fit: BoxFit.contain,
        ),
        )),
        Expanded(
        flex: 5,
        child: Center(
        child: Text(
        "Scan Physical Ticket Below",
        style: TextStyle(
        fontWeight: FontWeight.bold,
        fontSize: 45.0)))),
        Expanded(
        flex: 1,
        child: Container(
        alignment: Alignment.centerLeft,
        padding: EdgeInsets.symmetric(
        horizontal: 10.0, vertical: 5.0),
        child: Image.asset(
        'images/downarrow.png',
        fit: BoxFit.contain,
        ),
        )),
        ])))
        ],
        ),
        ));





        share|improve this answer













        The solution hit me when I was in the shower this morning:



        Start with a column that you break into two Expanded widgets to get the top/bottom section ration desired.



        Then in each Expanded, make a child container expanded to fill space. In the top container, set alignment to topCenter and set bottom container alignment to bottomCenter



        In the top container, add a SingleChildScrollView child. Now the upper section is scrollable and bottom is fixed.



         Widget getInputView() {
        return Builder(
        builder: (context) => Container(
        constraints: BoxConstraints.expand(),
        child: Column(
        children: <Widget>[
        Expanded(
        flex: 4,
        child: Container(
        alignment: Alignment.topCenter,
        constraints: BoxConstraints.expand(),
        child: SingleChildScrollView(
        child: Form(
        key: _formKey,
        child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: [
        Padding(
        padding: const EdgeInsets.all(10.0),
        child: Row(
        mainAxisAlignment:
        MainAxisAlignment.end,
        mainAxisSize: MainAxisSize.max,
        children: [
        Text("$_kiosk.kioskName",
        textAlign: TextAlign.end)
        ]),
        ),
        Padding(
        padding: EdgeInsets.symmetric(vertical:30.0),
        child: Text(
        _kiosk.displayMessage ?? "Welcome!",
        textAlign: TextAlign.center,
        style: TextStyle(
        fontSize: 45.0,
        color: Colors.black)),
        ),
        Padding(
        padding: EdgeInsets.all(20.0),
        child: Text(
        "Scan barcode below or enter search data in box.",
        style: TextStyle(
        fontSize: 25.0,
        color: Colors.black)),
        ),
        Row(
        mainAxisAlignment:
        MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.max,
        children: [
        Expanded(
        flex: 4,
        child: Container(
        margin: EdgeInsets.symmetric(
        horizontal: 50.0,
        vertical: 25.0),
        color: themeData
        .primaryColor,
        padding: const EdgeInsets
        .symmetric(
        horizontal: 25.0,
        vertical: 25.0),
        child: Center(
        child: new TextFormField(
        //This autofocus works, but during transition from successful plate val to
        //this page, the keyoard is activated during transition causing an overflow on the
        //applyValidationScreen.
        //autofocus: true,
        style: new TextStyle(
        decorationColor:
        themeData
        .accentColor,
        fontSize: 90.0,
        color:
        themeData
        .accentColor),
        textAlign:
        TextAlign.center,
        onSaved: (String value)
        this._data.plateNumber =
        value;
        ,
        decoration: new InputDecoration(
        hintText:
        "Enter Data",
        hintStyle:
        new TextStyle(
        color: Colors
        .white),
        fillColor:
        themeData
        .accentColor,
        contentPadding:
        EdgeInsets.all(
        1.0),
        border:
        InputBorder.none),
        validator: (value)
        if (value.isEmpty)
        return 'Field cannot be blank.';

        ,
        autocorrect: false,
        ),
        ))),
        Expanded(
        flex: 1,
        child: Padding(
        padding:
        const EdgeInsets.all(25.0),
        child: RaisedButton(
        padding: EdgeInsets.all(15.0),
        color: themeData
        .accentColor,
        onPressed: () async
        FocusScope.of(context)
        .requestFocus(
        new FocusNode());

        if (_formKey.currentState
        .validate())
        // If the form is valid, we want to show a Snackbar
        Scaffold.of(context)
        .showSnackBar(
        new SnackBar(
        content: Row(
        mainAxisAlignment:
        MainAxisAlignment
        .spaceBetween,
        children: [
        new CircularProgressIndicator(
        valueColor: new AlwaysStoppedAnimation<
        Color>(
        themeData
        .primaryColor),
        ),
        Text(
        'Search for matching ticket..',
        style: new TextStyle(
        color: themeData
        .primaryColor))
        ],
        ),
        backgroundColor:
        themeData
        .accentColor,
        duration: Duration(
        seconds: 10)),
        );
        await new Future.delayed(
        const Duration(
        milliseconds:
        1000));
        PlateMatchResponse resp =
        await this.submit();

        Scaffold.of(context)
        .hideCurrentSnackBar();

        Navigator.push(
        context,
        new MaterialPageRoute(
        builder: (context) =>
        new SvalKioskApp()),
        );

        ,
        child: new Text(
        'Search for Data Match',
        textAlign:
        TextAlign.center,
        style: TextStyle(
        fontSize: 25.0,
        color: Colors.black)),
        ),
        ))
        ]),
        ]),
        ),
        ))),
        Expanded(
        flex: 1,
        child: Container(
        padding: EdgeInsets.all(25.0),
        alignment: Alignment.bottomCenter,
        constraints: BoxConstraints.expand(),
        child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
        Expanded(
        flex: 1,
        child: Container(
        alignment: Alignment.centerRight,
        padding: EdgeInsets.symmetric(
        horizontal: 10.0, vertical: 5.0),
        child: Image.asset(
        'images/downarrow.png',
        fit: BoxFit.contain,
        ),
        )),
        Expanded(
        flex: 5,
        child: Center(
        child: Text(
        "Scan Physical Ticket Below",
        style: TextStyle(
        fontWeight: FontWeight.bold,
        fontSize: 45.0)))),
        Expanded(
        flex: 1,
        child: Container(
        alignment: Alignment.centerLeft,
        padding: EdgeInsets.symmetric(
        horizontal: 10.0, vertical: 5.0),
        child: Image.asset(
        'images/downarrow.png',
        fit: BoxFit.contain,
        ),
        )),
        ])))
        ],
        ),
        ));






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 19 '18 at 19:15









        JeffreyJeffrey

        3816




        3816























            0














            How about replacing the SingleChildScrollView with a Column and then setting the resizeToAvoidBottomPadding property of the Scaffold to false so you don't need the scrollview, since the keyboard will not force the layout to resize.






            share|improve this answer























            • I did start with this. In this case, the keyboard would then cover part of the view, including part of the input box as it is closer to the center of screen and the layout is landscape. However, if the input box was placed above the location where the keyboard would display, this would work.

              – Jeffrey
              Nov 21 '18 at 15:59















            0














            How about replacing the SingleChildScrollView with a Column and then setting the resizeToAvoidBottomPadding property of the Scaffold to false so you don't need the scrollview, since the keyboard will not force the layout to resize.






            share|improve this answer























            • I did start with this. In this case, the keyboard would then cover part of the view, including part of the input box as it is closer to the center of screen and the layout is landscape. However, if the input box was placed above the location where the keyboard would display, this would work.

              – Jeffrey
              Nov 21 '18 at 15:59













            0












            0








            0







            How about replacing the SingleChildScrollView with a Column and then setting the resizeToAvoidBottomPadding property of the Scaffold to false so you don't need the scrollview, since the keyboard will not force the layout to resize.






            share|improve this answer













            How about replacing the SingleChildScrollView with a Column and then setting the resizeToAvoidBottomPadding property of the Scaffold to false so you don't need the scrollview, since the keyboard will not force the layout to resize.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 20 '18 at 7:47









            01leo01leo

            526114




            526114












            • I did start with this. In this case, the keyboard would then cover part of the view, including part of the input box as it is closer to the center of screen and the layout is landscape. However, if the input box was placed above the location where the keyboard would display, this would work.

              – Jeffrey
              Nov 21 '18 at 15:59

















            • I did start with this. In this case, the keyboard would then cover part of the view, including part of the input box as it is closer to the center of screen and the layout is landscape. However, if the input box was placed above the location where the keyboard would display, this would work.

              – Jeffrey
              Nov 21 '18 at 15:59
















            I did start with this. In this case, the keyboard would then cover part of the view, including part of the input box as it is closer to the center of screen and the layout is landscape. However, if the input box was placed above the location where the keyboard would display, this would work.

            – Jeffrey
            Nov 21 '18 at 15:59





            I did start with this. In this case, the keyboard would then cover part of the view, including part of the input box as it is closer to the center of screen and the layout is landscape. However, if the input box was placed above the location where the keyboard would display, this would work.

            – Jeffrey
            Nov 21 '18 at 15:59

















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53329366%2fflutter-layout-with-fixed-bottom-section-and-scrollable-upper-section%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Top Tejano songwriter Luis Silva dead of heart attack at 64

            ReactJS Fetched API data displays live - need Data displayed static

            政党