Flutter: Tips and tricks

Resultado de imagem para flutter

ALERT: this is an ONGOING article =)! Some cool stuffs may appear with no warning.

Hi beloved heroes! I’m learning Flutter and this is (for now) a challenging framework for a lot of reasons:

  • It is a new framework, so documentation is not clear at crucial points and stackoverflow is still growing.
  • It looks intuitive, but it isn’t (try to add a TextField without a Material widget ancestor to see a demoniac error appears).
  • Have 634524143414 widgets available, it’s a little bit confusing to a beginner.
  • The free course (https://br.udacity.com/course/build-native-mobile-apps-with-flutter--ud905) is not for dummies (it’s hard in truly because the explanations are much faster — they explain router in 50 seconds, good luck).
  • I’m still learning =P.

So, for these reasons, I decided to share with you all little tricks that I spend some time do discover myself. Enjoy =).

Again: This is an ONGOING article. I will place here some tips and tricks about my flutters experiences. This will be updated article for each trick I discover.

The project that I am developing is here: https://github.com/benhurott/flutter-demo

#1: Hide keyboard when tap out the textfield:

Wrap your component with GestureDetector and call on tap:

_dismissKeyboard(BuildContext context) {
FocusScope.of(context).requestFocus(new FocusNode());
}

@override
Widget build(BuildContext context) {

return new GestureDetector(
onTap: () {
this._dismissKeyboard(context);
},
child: new Container(
color: Colors.white,
child: new Column(
children: <Widget>[/*...*/],
),
),
);
}

#2: Color RGB or Hex with Opacity

In Flutter, to create a color from RGB with alpha, use:

return new Container(
color: new Color.fromRGBO(0, 0, 0, 0.5),
);

To use hex-color:

return new Container(
color: new Color(0xFF4286f4),
);
//0xFF -> the opacity (FF for opaque)
//4286f4 -> the hex-color

Hex-color with opacity:

return new Container(
color: new Color(0xFF4286f4).withOpacity(0.5),
);
// or change the "FF" value 
// 100% — FF
// 95% — F2
// 90% — E6
// 85% — D9
// 80% — CC
// 75% — BF
// 70% — B3
// 65% — A6
// 60% — 99
// 55% — 8C
// 50% — 80
// 45% — 73
// 40% — 66
// 35% — 59
// 30% — 4D
// 25% — 40
// 20% — 33
// 15% — 26
// 10% — 1A
// 5% — 0D
// 0% — 00

#3: Using SafeArea to avoiding layout breaking

After June 2018, new ios apps and updates must have iPhone X compatibility (take a look). This device has a “particular” header that break our layout.

Instead using a Padding , it’s possible to use a SafeArea widget:

return new Container(
color: ColorPalette.primaryBlue, width: 80.0,
child: new SafeArea(
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
/*....*/
],
)
)
);

Without SafeArea , this is the result:

With SafeArea :

You can put aSafeArea widget inside specific component if you want =).

#4: Issue > InkWell feedback

We like feedbacks =). The docs say: “Hey guy, use InkWell!” but I tried and the touch feedback never appears.

After a search on the repository issues, I found an answer from passsy:

We must wrap our component with a transparentMaterial widget:

_onSelect() {
print('selected');
}

@override
Widget build(BuildContext context) {
return new Container(
color: ColorPalette.primaryBlue,
height: 80.0,
child: new Material(
color: Colors.transparent,
child: new InkWell(
splashColor: Colors.white.withOpacity(0.2),
onTap: this._onSelect,
child: new Center(/*...*/),
),
)
);
}

#5: Adding ListView inside a Column widget

If a ListView is a child of a Column widget, you will see this error:

flutter: ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
flutter: The following assertion was thrown during performResize():
flutter: Vertical viewport was given unbounded height.
flutter: Viewports expand in the scrolling direction to fill their container.In this case, a vertical
flutter: viewport was given an unlimited amount of vertical space in which to expand. This situation
flutter: typically happens when a scrollable widget is nested inside another scrollable widget.
flutter: If this widget is always nested in a scrollable widget there is no need to use a viewport because
flutter: there will always be enough vertical space for the children. In this case, consider using a Column
flutter: instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size
flutter: the height of the viewport to the sum of the heights of its children.

This occurs because Flutter cannot calculate the size of the screen.

This screen is a sample of the column with two principal widgets:

The first section is fixed at the top, so, it can’t be an item of the list (in my case). The second section is the list.

To solve this, just wrap your list with an Expanded widget:

new Column(
children: <Widget>[
this._renderSearch(),
new Expanded(child: this._renderChatList())
],
)

#6: Add Border Radius to Container

I really hoped this was more intuitive and documented, but…

new Container(
height: 40.0,
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: new BorderRadius.all(new Radius.circular(5.0))
),
)

#7: Image rounded from network

To create a “avatar image” that is rounded and the image is from network, use some like this:

new Container(
width: 50.0,
height: 50.0,
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(25.0),
image: new DecorationImage(
image: new NetworkImage('http://mysite/myimage.jpg'),
fit: BoxFit.cover
)
),
)