Flutter - SingleChildScrollView interfering in columns - dart

I created a screen that works well with the columns, but I needed to scroll because of the keyboard.
When you insert the SingleChildScrollView or the ListView attribute the MainAxisAlignment.spaceBetween, it no longer works.
Was there any solution for that?
Gif without the SingleChildScrollView the screen does not roll and the FloatingActionButton is at the bottom of the screen
Gif with SingleChildScrollView the screen roll and he FloatingActionButton is not in bottom of the screen
import 'package:flutter/material.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(backgroundColor: new Color(0xFF26C6DA)),
body: new SingleChildScrollView(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Container(
child: new Column(
children: <Widget>[
new TextField(
decoration: const InputDecoration(
labelText: "Description",
),
style: Theme.of(context).textTheme.title,
),
new TextField(
decoration: const InputDecoration(
labelText: "Description",
),
style: Theme.of(context).textTheme.title,
),
new TextField(
decoration: const InputDecoration(
labelText: "Description",
),
style: Theme.of(context).textTheme.title,
),
],
)
),
new Container(
margin: new EdgeInsets.only(bottom: 16.0),
child: new FloatingActionButton(
backgroundColor: new Color(0xFFE57373),
child: new Icon(Icons.check),
onPressed: (){}
),
)
],
),
)
);
}
}

I would recommend against using FloatingActionButton in the way you are doing here. FloatingActionButton should be used for actions that always need to always be on screen at all times. See the Material guidelines on button usage for suggestions on other button types that can be scrolled, like RaisedButton and FlatButton. You could use a RaisedButton here, but I think it would be better to make your screen a dialog and put the save action in the AppBar as I suggested in your other question.
If you do decide to use a RaisedButton or FlatButton, keep in mind that scrollables don't normally change their item spacing based on the size of their container. Instead of using MainAxisAlignment.spaceBetween, you could put some Padding around your RaisedButton to separate it from the TextField elements. This will ensure that they are spaced the same distance apart regardless of rotation, screen size, and regardless of whether the keyboard is up.

Follow the code below to register.
MainAxisAlignment.spaceBetween has been replaced with dynamic padding, depending on screen size.
import 'package:flutter/material.dart';
import 'dart:ui' as ui;
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
final ui.Size logicalSize = MediaQuery.of(context).size;
final double _height = logicalSize.height;
return new Scaffold(
appBar: new AppBar(backgroundColor: new Color(0xFF26C6DA)),
body: new SingleChildScrollView(
child: new Column(
//mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Container(
height: 300.0,
child: new Column(
children: <Widget>[
new TextField(
decoration: const InputDecoration(
labelText: "Description",
),
style: Theme.of(context).textTheme.title,
),
new TextField(
decoration: const InputDecoration(
labelText: "Description",
),
style: Theme.of(context).textTheme.title,
),
new TextField(
decoration: const InputDecoration(
labelText: "Description",
),
style: Theme.of(context).textTheme.title,
),
],
)
),
new Container(
padding: new EdgeInsets.only(top: (_height - 450.0)),
margin: new EdgeInsets.only(bottom: 16.0),
child: new FloatingActionButton(
backgroundColor: new Color(0xFFE57373),
child: new Icon(Icons.check),
onPressed: (){}
),
)
],
),
)
);
}
}

Related

Flutter FlatButton does not show tap animation / ripple effect

I have the following code:
return new ListTile(
leading: new CircleAvatar(
backgroundColor: Colors.blue,
child: new Image.network(
"http://res.cloudinary.com/kennyy/image/upload/v1531317427/avatar_z1rc6f.png")),
title: new Row(
children: <Widget>[
new Expanded(child: new Text(message)),
new FlatButton(onPressed: null, child: new Text("Delete"))
]
),
subtitle: new Text(from),
);
which created a tile in my ListView.
Each tile should have a button.
When I tap the button - I don't see any ripple effect or animation that I actually clicked. I was pretty sure it's a part of the Material theme as a gesture for FlatButtons, but I tried a solution I found, using InkWell:
return new ListTile(
leading: new CircleAvatar(
backgroundColor: Colors.blue,
child: new Image.network(
"http://res.cloudinary.com/kennyy/image/upload/v1531317427/avatar_z1rc6f.png")),
title: new Row(
children: <Widget>[
new Expanded(child: new Text(message)),
InkWell(
child: FlatButton(onPressed: null, child: new Text("Delete"), color: Colors.amber))
]
),
subtitle: new Text(from),
);
But still - my listview button does not have any ripple effect when tapped.
Any idea?
Flutter buttons are disabled by default. To enable a button, set its onPressed or onLongPress properties to a non-null value.
The ripple is not visible because you've set the property of your onPressed to null.
new FlatButton(onPressed: null, child: new Text("Delete"))
Change the onPressed property to something like this:
new FlatButton(onPressed: (){}, child: new Text("Delete"))
To compare here is an example of a no-null onPressed and a null valued onPressed.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListTile(
leading: new CircleAvatar(
backgroundColor: Colors.blue,
child: new Image.network(
"http://res.cloudinary.com/kennyy/image/upload/v1531317427/avatar_z1rc6f.png")),
title: new Row(children: <Widget>[
//new Expanded(child: new Text(message)),
new TextButton(
onPressed: () {},
child: new Text("Delete"),
),
new TextButton(
onPressed: null,
child: new Text("Delete"),
)
]),
//subtitle: new Text(from),
),
);
}
}
*Note that the FlatButton is now deprecated so I've used TextButton in the example.

How can I dispose Flutter WebviewScaffold on screen change?

I have a main screen that shows a header image with button to route to second screen, and a webview(scaffold) in a container below it. When I change to the second screen, the webview is still there.
This seems to be a similar problem to this one (Flutter: to close a webview when you left the page), but I can't figure out how to implement the dispose event. Can anyone help?
I am using the flutter_webview_plugin package.
Here is my code:
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'dart:async';
import './SecondScreen.dart';
String selectedUrl = 'https://flutter.io';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
final flutterWebViewPlugin = FlutterWebviewPlugin();
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Generated App',
theme: new ThemeData(
primarySwatch: Colors.purple,
primaryColor: const Color(0xFF8e80a8),
accentColor: const Color(0xFF8e80a8),
canvasColor: const Color(0xFF8e80a8),
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(color: Color(0xFF8e80a8)),
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(10, 30, 10, 5),
child: new Image.asset(
'lib/assets/newoldralogo1.png',
),
),
Container(
constraints: BoxConstraints.expand(
height:
Theme.of(context).textTheme.display1.fontSize * 1.1 + 10.0,
),
child: new Stack(fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(color: Color(0xFF8e80a8)),
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 10),
child: Image.asset(
"lib/assets/newoldralogo1.png",
alignment: Alignment.topCenter,
fit: BoxFit.fitWidth,
),
),
),
Container(
child: RaisedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
},
color: Color(0xFFFFFF),
),
),
]),
),
Container(
constraints: BoxConstraints.expand(
height:
Theme.of(context).textTheme.display1.fontSize * 1.1 + 300.0,
),
padding: const EdgeInsets.fromLTRB(10, 15, 10, 5),
color: Color(0xFF8e80a8),
alignment: Alignment.center,
child: Container(
child: WebviewScaffold(
url:
('https://flutter.io/'),
),
),
)
]),
);
}
}
/*
#override
void dispose() {
super.dispose();
_MyHomePageState();
}
*/
A solution is to change the "Navigator.push" to "Navigator.pushRemove." This will mean that the first screen will not reappear, so pressing the back button (on an Android device, at least) will exit the app.
It's not quite what I was trying to do, but will work for now.
If anyone could show me where to put the "dispose" thing, I would still love to know! In the meantime, I will just keep plugging along. Thanks to those who have shared so much helpful information around the web!
By the way, here is the new code, cleaned up a bit:
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import './SecondScreen.dart';
class WebView extends StatefulWidget {
#override
_WebViewState createState() => _WebViewState();
}
class _WebViewState extends State<WebView> {
TextEditingController controller = TextEditingController();
FlutterWebviewPlugin flutterWebviewPlugin = FlutterWebviewPlugin();
var urlString =
"https://stackoverflow.com/questions/43692923/flutter-container-onpressed";
launchUrl() {
setState(() {
urlString = controller.text;
flutterWebviewPlugin.reloadUrl(urlString);
});
}
#override
void initState() {
super.initState();
flutterWebviewPlugin.onStateChanged.listen((WebViewStateChanged wvs) {
print(wvs.type);
});
}
//this part isn't working
#override
void dispose() {
_WebViewState();
// close the webview here
super.dispose();
}
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(color: Color(0xFF8e80a8)),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new GestureDetector(
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
},
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 40, 10, 10),
child: new Container(
constraints: BoxConstraints.expand(
height: Theme.of(context).textTheme.display1.fontSize * 1.1 +
40.0,
),
child: new Image.asset(
'lib/assets/newoldralogo1menubutton3.png',
alignment: Alignment.topCenter,
fit: BoxFit.fitWidth,
)),
),
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Container(
constraints: BoxConstraints.expand(
height: Theme.of(context).textTheme.display1.fontSize * 1.1 + 250.0,
),
child: WebviewScaffold(
url: urlString,
withZoom: false,
),
),
),
],
),
);
}
}
Hiding the web view when the user navigates to the second screen
flutterWebViewPlugin.hide();
and showing it again when the user navigates back
flutterWebViewPlugin.show();
should solve the issue. By using this way user can navigate back to the first screen after navigating to the second screen.
Remember to await the Navigator.push() to the second screen.
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'dart:async';
import './SecondScreen.dart';
String selectedUrl = 'https://flutter.io';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
final flutterWebViewPlugin = FlutterWebviewPlugin();
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Generated App',
theme: new ThemeData(
primarySwatch: Colors.purple,
primaryColor: const Color(0xFF8e80a8),
accentColor: const Color(0xFF8e80a8),
canvasColor: const Color(0xFF8e80a8),
),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(color: Color(0xFF8e80a8)),
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.fromLTRB(10, 30, 10, 5),
child: new Image.asset(
'lib/assets/newoldralogo1.png',
),
),
Container(
constraints: BoxConstraints.expand(
height:
Theme.of(context).textTheme.display1.fontSize * 1.1 + 10.0,
),
child: new Stack(fit: StackFit.expand,
children: <Widget>[
Container(
decoration: BoxDecoration(color: Color(0xFF8e80a8)),
child: Padding(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 10),
child: Image.asset(
"lib/assets/newoldralogo1.png",
alignment: Alignment.topCenter,
fit: BoxFit.fitWidth,
),
),
),
Container(
child: RaisedButton(
onPressed: () async {
flutterWebViewPlugin.hide();
await Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
flutterWebViewPlugin.show();
},
color: Color(0xFFFFFF),
),
),
]),
),
Container(
constraints: BoxConstraints.expand(
height:
Theme.of(context).textTheme.display1.fontSize * 1.1 + 300.0,
),
padding: const EdgeInsets.fromLTRB(10, 15, 10, 5),
color: Color(0xFF8e80a8),
alignment: Alignment.center,
child: Container(
child: WebviewScaffold(
url:
('https://flutter.io/'),
),
),
)
]),
);
}
}

How to customize the SliverAppBar widget in flutter?

I would like to add some more information in the green area, but when user scrolls up, I keep the _ SliverAppBar on the top..., like this:
Here is my current source code:
body: new CustomScrollView(slivers: <Widget>[
const SliverAppBar(
pinned: true,
expandedHeight: 300.0, // TODO: check out later
flexibleSpace: const FlexibleSpaceBar(
title: const Text('_SliverAppBar')
),
),
new SliverList(delegate: new SliverChildListDelegate(_galleryListItems()))
]),
The FlexibleSpaceBar has a background property the accepts any Widget
Use to build the information you need:
FlexibleSpaceBar(
title: Text('_SliverAppBar'),
background: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Info'),
],
),
),
Here is a more complete example that adds a subtitle and hides it when the user scrolls.
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'My Flutter Pad'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
const kExpandedHeight = 300.0;
class _MyHomePageState extends State<MyHomePage> {
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
leading: Icon(Icons.menu),
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.search),
highlightColor: Colors.white,
onPressed: () {},
),
],
expandedHeight: 200.0,
floating: false,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
centerTitle: true,
background: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/bar.jpg"),
fit: BoxFit.cover)),
child: Column(
children: [
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('NEW GAME'),
Text('Sekiro: Shadows Dies Twice'),
RaisedButton(
onPressed: () {},
child: Text('Play'),
),
],
),
),
),
],
),
)),
),
];
},
body: Center(
child: Text("Sample Text"),
),
),
);
}
}

How to read data from Flutter elements

I've the below code for entering some data, I do not know how to handle it!
i.e. What shall I write at the onPressed for the IconButton so that the data is read from all the elements (name, birthday, ...)? and how to display it in Dialog to check if read correctly?
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.deepOrange,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var _value=false;
double _bodyHeight=0.0;
void onchange(bool value) {
setState(() {
_value = value;
this._bodyHeight = (value == true) ? 400.0 : 0.0;
});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.grey[500],
appBar: new AppBar(
title: new Text(widget.title),
),
body: new SingleChildScrollView(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Card(
child: new Container(
height: 50.0,
child: new Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
new Text("Select me pls"),
new Switch(value: _value, onChanged: (bool value) => onchange(value)),
],
),
),
),
new Card(
child: new AnimatedContainer(
child: new ListView(
children: <Widget>[
new ListTile(
leading: const Icon(Icons.person),
title: new TextField(
decoration: new InputDecoration(
hintText: "Name",
),
),
),
new ListTile(
leading: const Icon(Icons.phone),
title: new TextField(
decoration: new InputDecoration(
hintText: "Phone",
),
),
),
new ListTile(
leading: const Icon(Icons.email),
title: new TextField(
decoration: new InputDecoration(
hintText: "Email",
),
),
),
const Divider(
height: 1.0,
),
new ListTile(
leading: const Icon(Icons.label),
title: const Text('Nick'),
subtitle: const Text('None'),
),
new ListTile(
leading: const Icon(Icons.today),
title: const Text('Birthday'),
subtitle: const Text('February 20, 1980'),
),
new IconButton(icon: const Icon(Icons.save),
onPressed: null
/*
*
* What shall I write here to read the data in the elements
*
*
*
* */
),
],
),
curve: Curves.easeInOut,
duration: const Duration(milliseconds: 500),
height: _bodyHeight,
// color: Colors.red,
),
),
],
),
),
);
}
}
One way is that TextFields take a property called TextEditingController which allow you to access the value of the TextField.
And to show a dialog you can just call showDialog() function.
class TextFieldExample extends StatefulWidget {
#override
_TextFieldExampleState createState() => new _TextFieldExampleState();
}
class _TextFieldExampleState extends State<TextFieldExample> {
TextEditingController c1;
TextEditingController c2;
#override
void initState() {
c1 = new TextEditingController();
c2 = new TextEditingController();
super.initState();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new TextField (
controller: c1,
),
new TextField(
controller: c2,
),
new OutlineButton(onPressed: () {
showDialog(child: new AlertDialog(
content: new Text("You entered ${c1.text} ${c2.text} ")
),
context: context
);
},
child: new Text("Show Dialog"),
)
],
),
),
);
}
}

Can FlutterLogo be made to stretch-to-fill?

I would like to display a large FlutterLogo in my app:
https://docs.flutter.io/flutter/material/FlutterLogo-class.html
In order to account for varying screen sizes I would like to make it stretch-to fill. Is that possible? Or do I need to use a MediaQuery to determine the parent's size and pass that into FlutterLogo(size:)?
My current code:
Widget build(BuildContext context) {
return new Center(
child: new FlutterLogo(size: 800.0, style: FlutterLogoStyle.horizontal, textColor: Colors.white),
);
}
You can accomplish this with a ConstrainedBox:
import 'package:flutter/material.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
theme: new ThemeData.dark(),
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('Example App')),
body: new ConstrainedBox(
constraints: new BoxConstraints.expand(),
child: new FlutterLogo(
style: FlutterLogoStyle.horizontal,
textColor: Colors.white,
),
),
);
}
}
I believe I have answered a similar question
How to stretch an icon to fill parent?
https://docs.flutter.io/flutter/widgets/Expanded-class.html
https://groups.google.com/forum/#!msg/flutter-dev/lsgdU1yl7xc/0pYS2qrzBQAJ
https://docs.flutter.io/flutter/widgets/FittedBox-class.html
https://docs.flutter.io/flutter/painting/BoxFit-class.html
new Expanded(
child: new FittedBox(
fit: BoxFit.fill,
child: new FlutterLogo( style: FlutterLogoStyle.horizontal, textColor: Colors.white),
),
),
I feel kinda strange. Looking at the OP profile ID, I wonder if I answer the question correctly.
I hope this helps.
used this code to run it
import 'package:flutter/material.dart';
class MyAppBar extends StatelessWidget {
MyAppBar({this.title});
// Fields in a Widget subclass are always marked "final".
final Widget title;
#override
Widget build(BuildContext context) {
return new Container(
height: 56.0, // in logical pixels
padding: const EdgeInsets.symmetric(horizontal: 8.0),
decoration: new BoxDecoration(color: Colors.blue[500]),
// Row is a horizontal, linear layout.
child: new Row(
// <Widget> is the type of items in the list.
children: <Widget>[
new IconButton(
icon: new Icon(Icons.menu),
tooltip: 'Navigation menu',
onPressed: null, // null disables the button
),
// Expanded expands its child to fill the available space.
new Expanded(
child: title,
),
new IconButton(
icon: new Icon(Icons.search),
tooltip: 'Search',
onPressed: null,
),
],
),
);
}
}
class MyScaffold extends StatelessWidget {
#override
Widget build(BuildContext context) {
// Material is a conceptual piece of paper on which the UI appears.
return new Material(
// Column is a vertical, linear layout.
child: new Column(
children: <Widget>[
new MyAppBar(
title: new Text(
'Example title',
style: Theme.of(context).primaryTextTheme.title,
),
),
new Expanded(
child: new FittedBox(
fit: BoxFit.fill,
child: new FlutterLogo( style: FlutterLogoStyle.horizontal, textColor: Colors.white),
),
),
],
),
);
}
}
void main() {
runApp(new MaterialApp(
title: 'My app', // used by the OS task switcher
home: new MyScaffold(),
));
}
edit: I posted complete code just for darky, since I forgot to mention that expanded needs to be wrapped into row, column, or flex container to expand

Resources