Skip to content

Instantly share code, notes, and snippets.

@raison00
Last active April 17, 2020 18:05
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/b11a9a7dedf70500d9fb8bd215d86de6 to your computer and use it in GitHub Desktop.
Save raison00/b11a9a7dedf70500d9fb8bd215d86de6 to your computer and use it in GitHub Desktop.
Sample Overflow Challenge: Using CustomMultiChild Layout to Resolve RenderOverflow Errors
// This version of the code gives exposure to another tricky layout issue.
// There is no blantant render overflow issue using the CustomMultiChild
import 'package:flutter/material.dart';
void main() {
runApp(RenderOverflowResolution());
}
class RenderOverflowResolution extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MultiChildDemo(title: 'Flutter CustomMultiChildLayout Solution'),
);
}
}
// CustomMultiChildLayout Solution
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: Center(
child: CustomMultiChildLayout(
delegate: YourLayoutDelegate(),
children: <Widget>[
LayoutId(
id: 'icon_channel',
// Left Layout Channel. (child 1) The id can be anything, i.e. any Object, an enum value.
child: Card(
child: Padding(
padding: const EdgeInsets.all(18.0),
child: Icon(Icons.message),
),
),
),
LayoutId(
id: 'overflow_area',
// Right Layout Channel. (child 2) 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.
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children:[
Padding(padding: const EdgeInsets.all(28.0),
child: Text(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed"
" do eiusmod tempor incididunt ut labore et dolore magna "
"aliqua. Ut enim ad minim veniam, quis nostrud "
"exercitation ullamco laboris nisi ut aliquip ex ea "
"commodo consequat.",
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold,fontSize: 22.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
void performLayout(Size size) {
// `size` is the size of the `CustomMultiChildLayout` itself.
Size leadingSize = Size
.zero;
// If there is no widget with id `icon_channel`, the size will remain at zero.
if (hasChild('icon_channel')) {
leadingSize = layoutChild(
'icon_channel', // (child 1)
BoxConstraints.tightFor(
height: size
.height),
// Tight means the child cannot be bigger than the whole layout. it's forced to fill the allocated space.
);
// No need to position this to have it at Offset(0, 0).
}
//This resolves the render overflow error using tight constraints.
if (hasChild('overflow_area')) {
final secondSize = layoutChild(
'overflow_area',
// (child 2)
BoxConstraints.tightFor(width: size.width/2),
);
positionChild(
'overflow_area',
Offset(
leadingSize.width,
// This will place 'overflow_area' (child 2) to the right of 'icon_channel' (child 1).
size.height / 2 -
secondSize.height / 2,
// Centers the 'overflow_area' (child 2) vertically.
),
);
}
}
@override
bool shouldRelayout(YourLayoutDelegate oldDelegate) {
return oldDelegate.position != position;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment