Let's Code Flutter: 3 Useful Widgets
Tags: flutter, dart, android
Published: 2021-03-30 13:21:48

---
title: Let's Code Flutter: 3 Useful Widgets
published: true
description: There are so many Widgets, and each of them does so many things. Here are a few of the ones I've been using lately to get my work done.
tags: flutter, dart, android
cover_image: https://www.gatling.xyz/content/images/2021/03/letscodeflutter_3usefulwidgets.png
canonical_url: https://www.gatling.xyz/blog/2021/03/29/flutter-three-useful-widgets
---
There are *so many* Widgets, and each of them does so many things. In a lot of cases, you can think of Widgets as various upgrades to other Widgets. And the way Flutter seems to be optimized, there's no limit to how many Widgets you can apply to other Widgets. Here are three Widgets that I've been using lately to help me get my work done.

## GestureDetector

Personally, this one is named slightly deceptively, but that's only because I'm coming from a pure Android development background. But this handy little widget behaves like most others: it adds behavior to its children. 

In Android, to have something react to presses, you would give it an `onClickListener`. Simple enough, and all Views support it. Similarly in Flutter, you would instead wrap the child you want to handle these presses in a `GestureDetector` widget.

```dart
@override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => handleTap(),
      child: Container(),
    );
  }
```

You can also handle *a million (Citation needed)* other types of gestures. 

![https://www.gatling.xyz/content/images/2021/03/gesturedetector.png](https://www.gatling.xyz/content/images/2021/03/gesturedetector.png)

Here's a *small* snippet of everything `GestureDetector` has to offer. As well as handling taps, I've used it to handle panning, similar to how a Slider functions.

## LayoutBuilder

Sometimes you need a child widget to depend on the parent's size. During the `build`, this is generally not available. However, you can get what you need by wrapping the child in a `LayoutBuilder` widget.

```dart
@override
  Widget build(BuildContext context) {
    return Scaffold(
        body: SafeArea(
            child: Container(
                margin: EdgeInsets.all(5.0),
                child: LayoutBuilder(
                  builder: (context, BoxConstraints layout) {
                    return Container(
                      width: layout.maxWidth / 3,
                      height: layout.maxHeight / 3,
                      child: Container(),
                    );
                  },
                )
            )
        )
    );
  }
```

Inside a Scaffold, inside a SafeArea, inside a Container with margins, we want to act on the constraints of the space we have left. The constraints contain the minimum and maximum width and height available to us.

## ValueListenableBuilder

This is a new Widget for me, and I'm still trying to figure out the best/optimal use case for it. [In my original post about switching to Flutter](https://www.gatling.xyz/blog/2021/02/22/lets-code-flutter-making-the-switch/), I list a few widgets that I assume will be your "bread and butter," making up the majority of the widgets you use. In that list I mention **`StreamBuilder`,** a Widget that takes a Stream and calls its builder every time the stream emits items.

A `ValueListenableBuilder` performs almost exactly the same way, except it listens to a `ValueNotifier`, then emits that value to its builder whenever it changes.

```dart
ValueNotifier<bool> _showEmptyView = ValueNotifier(false);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: [
          ValueListenableBuilder<bool>(
            valueListenable: _showEmptyView,
            builder: (context, _showEmptyView, child) {
              if (_showEmptyView) {
                return Container(
                    color: Colors.red,
                    child: ...
                );
              } else {
                return Container(
                    color: Colors.blue,
                    child: ...
                );
              }
            },
          ),
          ElevatedButton(
            onPressed: () {
              _showEmptyView.value = !_showEmptyView.value;
            },
            child: Text("Press me"),
          )
        ],
      ),
    );
  }
```

Depending on your layout and optimization needs, you could ignore this Widget and just call `setState`, updating a show/hide boolean. Or you could create a custom StatefulWidget that handles the state, which is actually what ValueListenableBuilder is. 

If you have any insight into this Widget, please share!

---

Head on over to the Flutter official documentation for more information on these amazing widgets.

- [GestureDetector](https://api.flutter.dev/flutter/widgets/GestureDetector-class.html)
- [LayoutBuilder](https://api.flutter.dev/flutter/widgets/LayoutBuilder-class.html)
- [ValueListenableBuilder](https://api.flutter.dev/flutter/widgets/ValueListenableBuilder-class.html) with [ValueNotifier](https://api.flutter.dev/flutter/foundation/ValueNotifier-class.html)

What are some Widgets you've been using lately? Let me know in the comments and help me find something new to play around with!