Skip to content

Instantly share code, notes, and snippets.

@raison00
Last active April 22, 2020 15:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raison00/fb4ce93653187da22f9cfdb9eab7af52 to your computer and use it in GitHub Desktop.
Save raison00/fb4ce93653187da22f9cfdb9eab7af52 to your computer and use it in GitHub Desktop.
Overflow Solution: Using CustomMultiChild Layout to Resolve RenderOverflow Errors
// for Flutter Inspector layout tools: visualizing render overflow solutions
// This example is adapted from SO "How to use CustomMultiChildLayout & CustomSingleChildLayout in Flutter"
//https://stackoverflow.com/questions/59483051/how-to-use-custommultichildlayout-customsinglechildlayout-in-flutter/59483482#59483482
import 'package:flutter/material.dart';
void main() {
runApp(ColumnOverflow());
}
class ColumnOverflow extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MultiChildDemo(title: 'CustomMultiChild Layout'),
);
}
}
// CustomMultiChildLayout Solution for Text Render Overflow Issues
class MultiChildDemo extends StatefulWidget {
MultiChildDemo({Key key, this.title}) : super(key: key);
final String title;
@override
_MultiChildDemoState createState() => _MultiChildDemoState();
}
class _MultiChildDemoState extends State<MultiChildDemo> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
child: CustomMultiChildLayout(
delegate: YourLayoutDelegate(),
children: <Widget>[
// Left Layout Side.
LayoutId(
// (child 1) The id can be any Object or any enum value.
id: 'icon_channel',
child: Card(
child: Padding(
padding: const EdgeInsets.all(18.0),
child: Icon(Icons.message),
),
),
),
// Right Layout Side.
LayoutId(
// (child2) This is the area where the text is overflowing in the sample app.
//To deal with overflow issues, use this id for laying out your children.
id: 'overflow_area',
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Title", style: Theme.of(context).textTheme.headline4),
Text(
"This is the primary widget with the layout issue."
"The goal here is to make the widget have the text block have multilines cascading down the page , not just a single line. This shows how to deal with a large chunk of text."
" this is Widget Two. widget two. Widget Two. This is the primary widget."
"The goal here is to make the widget the prominent widget, not widget one, and no text running off the screen. "
"Widget Two. This is for showing proof of overflow text rendering the primary widget",
maxLines: 10,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
textDirection: TextDirection.ltr,
style: TextStyle(
color: Colors.grey[800],
fontWeight: FontWeight.bold,
fontSize: 14.0),
),
],
),
),
],
),
),
);
}
}
class YourLayoutDelegate extends MultiChildLayoutDelegate {
// You can pass parameters to this class because you will instantiate your delegate
// in the build function where you place your CustomMultiChildLayout.
// Note: using an Offset for this example.
YourLayoutDelegate({this.position});
final Offset position;
@override
// `size` is the size of the `CustomMultiChildLayout` itself.
void performLayout(Size size) {
// If there is no widget with id `icon_channel`, the size will remain at zero.
Size leadingSize = Size.zero;
if (hasChild('icon_channel')) {
leadingSize = layoutChild(
'icon_channel', // child 1.
// Tight means the child cannot be bigger than the whole layout.
BoxConstraints.tightFor(height: size.height),
);
// No need to position this to have it at Offset(0, 0).
}
//This resolves the render overflow error using the box constraints and again, using tight for the flex factor.
if (hasChild('overflow_area')) {
final secondSize = layoutChild(
'overflow_area',
BoxConstraints.tightFor(width: size.width / 2),
);
positionChild(
'overflow_area', // child 2.
Offset(
// This will place 'overflow_area' (child 2) to the right of 'icon_channel' (child 1).
leadingSize.width,
// Centers the 'overflow_area' (child 2) vertically.
size.height / 2 - secondSize.height / 2,
),
);
}
}
@override
bool shouldRelayout(YourLayoutDelegate oldDelegate) {
return oldDelegate.position != position;
}
}
@raison00
Copy link
Author

Updated to maintain content consistency of the example solution options for dealing with an overflow error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment