Pro and Semi-pro tips for Flutter.
Please contribute if you encounter anything too. Just file a PR!
- If you want the Material Design "ink splash" effect, use the
Inkwell
, but make sure that you have it as the child of aMaterial
widget. - If you use a
Container
instead and try to add a background color, the splash effect will be superseded by the background. - The ink splash will cooperate with a
Material
widget'scolor
parameter.
new Material(
color: Colors.blue[500], //Ink Splash will properly overlay
child: new InkWell( ... )
);
CircleAvatar will not radially clip its background image.
CircleAvatar
(despite the name) will not actually clip abackgroundImage
to a circle: Issue- The most performant approach is to probably pre-process any avatar image beforehand and clip it to a circle.
- However this is not always possible and brings additional overhead.
- Instead you can create a
Container
with equal width and height (to ensure that the clipped radial area is a perfect circle) and add aClipOval
widget as the child of that container. Then you can place the image as the child of theClipOval
;
// ClipOval will radially clip based on the parent
// If you have a rectangle with different height & width, then you will
// get an oval. If you have a square, you will get a circle.
new Container(
width: 40.0,
height: 40.0,
child: new ClipOval(
child: new Image( ... )
)
)
Use Stack to mimic "Absolute Positioning" in web land
- If you come from a web-dev background and you want to position a widget relative to another widget, the
Stack
widget is your friend. - Example:
- Say you want to add an "annotation icon" to a
CircleAvatar
: - Create a
Stack
with the avatar as the first child. The 'z-index' of each stack child will be based on order of appearance in the child list. - Because you want to position the icon relative to the avatar, you need to wrap it inside a
Positioned
widget which will place it relative to the stack. Add that as the next child in the list.
- Say you want to add an "annotation icon" to a
new Stack(
children: <Widget>[
new CircleAvatar( ... ),
// This will place the icon at the bottom right hand corner
new Positioned(
right: 2.0,
bottom: 2.0,
child: new Icon(...)
)
]
);
Use MediaQuery to retrieve the screen size if needed
- Use the
BuildContext
parameter of a widget's build function as the parameter forMediaQuery.of()
@override
Widget build(BuildContext context) {
Size screenSize = MediaQuery.of(context).size;
double width = screenSize.width;
double height = screenSize.height;
// ...
}
Use WidgetTester.pump if you have to test the end results of a user interaction that leads to many animations.
- You will need to "run through" the animations for a single interaction that lead to a sequence of events before something is done.
- An example is testing the effects of a
onDismissed
callback for aDismissable
widget (think swipe to delete). - After you use the
WidgetTester
to swipe the widget, the following events happen before theonDismissed
function is called:- The slide has to start
- The slide has to end
- The widget has to start shrinking vertically
- The widget has to finish shrinking
- The widget has to removed from the tree
- And only then does the
onDismissed
function gets called. - So make sure to call
WidgetTester.pump
for each event before testing the completed logic of the callback.
// Simulate the swipe
await tester.fling( ... )
// PUMP IT UP!!!
await tester.pump(); // start the slide
await tester.pump(const Duration(seconds: 1)); // finish the slide and start shrinking...
await tester.pump(); // first frame of shrinking animation
await tester.pump(const Duration(seconds: 1)); // finish the shrinking and call the callback...
await tester.pump(); // rebuild after the callback removes the entry
// Then test logic of completion of swipe
// ...
- Listen to Hustlin' by Rick Ross
- Sing along but replace all instances of
Hustlin'
withFlutterin'
- Expect to see about 30-50% less bugs in your Flutter code
- Repeat and prosper