Created
July 30, 2020 22:47
-
-
Save matthew-carroll/0c5beea2e2149faef98110edc9fb7bff to your computer and use it in GitHub Desktop.
Flutter web overflow bug | visual density | working
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
final Color darkBlue = Color.fromARGB(255, 18, 32, 47); | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
theme: ThemeData.dark().copyWith( | |
scaffoldBackgroundColor: darkBlue, | |
visualDensity: VisualDensity.adaptivePlatformDensity, | |
), | |
debugShowCheckedModeBanner: false, | |
home: Scaffold( | |
body: Center( | |
child: MyWidget(), | |
), | |
), | |
); | |
} | |
} | |
class MyWidget extends StatefulWidget { | |
@override | |
_MyWidgetState createState() => _MyWidgetState(); | |
} | |
class _MyWidgetState extends State<MyWidget> { | |
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); | |
void _validateForm() { | |
_formKey.currentState.validate(); | |
} | |
// This tree reproduces an overflow problem that I don't understand. | |
// Upon initial run everything is fine. Then, press the button that | |
// causes the error message to appear. Notice that suddenly there is | |
// an overflow error on the Column. | |
@override | |
Widget build(BuildContext context) { | |
return Container( | |
width: double.infinity, | |
height: double.infinity, | |
color: Colors.yellow, | |
child: _buildExpandOrScroll( | |
child: Center( | |
child: _buildCard( | |
child: _buildContent(), | |
), | |
), | |
), | |
); | |
} | |
// Builds a series of widgets that accomplish the concept of scrolling | |
// if the content exceeds the available space, or, if there is sufficient | |
// space to display the content then the content is given all available | |
// space to occupy. My use-case is the desire to vertically center my | |
// content when it does not overflow the available space. | |
Widget _buildExpandOrScroll({Widget child}) { | |
return LayoutBuilder( | |
builder: (BuildContext context, BoxConstraints constraints) { | |
return SingleChildScrollView( | |
child: ConstrainedBox( | |
constraints: BoxConstraints( | |
minHeight: constraints.maxHeight, | |
), | |
child: IntrinsicHeight( | |
child: child, | |
), | |
), | |
); | |
}, | |
); | |
} | |
// Builds a white card with rounded corners. Padding is applied outside | |
// the card, and inside the card. The content of the card is the provided | |
// "child" | |
Widget _buildCard({Widget child}) { | |
return Padding( | |
padding: const EdgeInsets.symmetric(vertical: 72), | |
child: ConstrainedBox( | |
constraints: BoxConstraints.loose(Size(400, double.infinity)), | |
child: Material( | |
color: Colors.white, | |
borderRadius: BorderRadius.circular(32), | |
elevation: 24, | |
child: Padding( | |
padding: const EdgeInsets.symmetric( | |
horizontal: 40, vertical: 20), | |
child: child, | |
), | |
), | |
), | |
); | |
} | |
// Builds the content of the card. Includes a title, a bunch of vertical | |
// space, an error message that may or may not be displayed, and a button | |
// that causes the error message to display. | |
Widget _buildContent() { | |
return Form( | |
key: _formKey, | |
child: Column( | |
mainAxisSize: MainAxisSize.min, | |
children: [ | |
Text( | |
'Some Title', | |
style: TextStyle( | |
fontSize: 30, | |
fontWeight: FontWeight.bold, | |
), | |
), | |
TextFormField( | |
decoration: InputDecoration( | |
hintText: 'some input...', | |
), | |
validator: (String value) { | |
return 'This is a form error'; | |
}, | |
), | |
SizedBox(height: 400), | |
SizedBox( | |
width: double.infinity, | |
child: RaisedButton( | |
color: Colors.grey.shade900, | |
padding: const EdgeInsets.all(24), | |
shape: RoundedRectangleBorder( | |
borderRadius: BorderRadius.circular(16), | |
), | |
child: Text( | |
'Do Something', | |
style: TextStyle( | |
color: Colors.white, | |
), | |
), | |
onPressed: () { | |
_validateForm(); | |
}, | |
), | |
), | |
SizedBox(height: 16), | |
], | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment