Currently, the app wouldn’t look right if you ran it on a device.
To make the buttons of the right shape and size, we need to wrap Rows, Columns, and the buttons themselves in Expanded.
We’ll expand some elements to make them exactly as big as we want them to be.
In this case, the main Column will be divided in the following way:
As was explained in Fill the Space Available in the View Using Expanded, the Expanded widget makes this really simple, requiring you to replace the calculator screen shown in the code with this:
| Expanded( |
| flex: 2, |
| child: Card( |
| color: Colors.lightGreen[50], |
| child: Padding( |
| padding: EdgeInsets.all(15.0), |
| child: Text( |
| _str, |
| textScaleFactor: 2.0, |
| ), |
| ), |
| ), |
| ), |
Similarly, the first Row widget (the one containing the delete buttons, shown in the code) will have to be replaced with:
| Expanded( |
| flex: 1, |
| child: Row( |
| ... |
| ) |
| ) |
and the one containing the number buttons (shown in the code) will similarly have to be replaced with:
| Expanded( |
| flex: 4, |
| child: Row( |
| ... |
| ) |
| ) |
Three quarters of the space will be taken up by the delete all button and one quarter by the delete one button.
This means that those two FlatButtons will have to be expanded by replacing them with FlatButtons wrapped in two Expanded widgets with flex values of, respectively, 3 and 1:
| Expanded( |
| flex: 3, |
| child: FlatButton( |
| child: Text( |
| 'C', |
| style: TextStyle(color: Colors.white), |
| ), |
| onPressed: (){deleteAll();}, |
| color: Colors.black54, |
| ), |
| ), |
| Expanded( |
| flex: 1, |
| child: FlatButton( |
| child: Text( |
| '<-', |
| style: TextStyle(color: Colors.white) |
| ), |
| onPressed: (){deleteOne();}, |
| color: Colors.black87, |
| ), |
| ), |
Similarly, you will need to expand the numbers’ Column with a flex of 3 and the operators’ Column with a flex of 1 to make the buttons all of the same size.
The number and operator buttons should all be of the same size, so they should all be wrapped in Expanded widgets with the same flex which, for simplicity, we’ll set to the value 1.
The same is true for the Rows of number buttons: they all need to be expanded with the same flex.
To avoid repetition and to speed up replacement of many widgets, we’ll build expanded FlatButton and Row classes, which will be called ExpandedButton and ExpandedRow.
They need to take all of the arguments and options we currently use, and build the corresponding widgets wrapped in Expanded.
They are defined, very simply, above main, in the following way:
| class ExpandedButton extends StatelessWidget { |
| |
| ExpandedButton({this.onPressed, this.child, this.color}); |
| |
| final Widget child; |
| final VoidCallback onPressed; |
| final Color color; |
| |
| @override |
| Widget build(BuildContext context) => |
| Expanded( |
| flex:1, |
| child: FlatButton( |
| onPressed: onPressed, |
| child: child, |
| color: color, |
| ), |
| ); |
| } |
| |
| class ExpandedRow extends StatelessWidget { |
| |
| ExpandedRow({this.children, this.crossAxisAlignment}); |
| |
| final List<Widget> children; |
| final CrossAxisAlignment crossAxisAlignment; |
| |
| @override |
| Widget build(BuildContext context) => |
| Expanded( |
| flex:1, |
| child: Row( |
| children: children, |
| crossAxisAlignment: crossAxisAlignment, |
| ), |
| ); |
| } |
After defining them, simply replace all of the operator button’s Row widgets with ExpandedRow widgets and all of the operator and number FlatButtons and the calculator’s layout should be complete.