Last active
April 17, 2020 18:05
-
-
Save raison00/b11a9a7dedf70500d9fb8bd215d86de6 to your computer and use it in GitHub Desktop.
Sample Overflow Challenge: Using CustomMultiChild Layout to Resolve RenderOverflow Errors
This file contains 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
// 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