ConditionalBuilder

Synchronous conditional widget builder.

Declaratively renders a widget based on a condition. Using this you can avoid implicit conditional statements in your code to show/hide a widget.

Use cases

Conditional widget rendering

Rendering widgets based on conditions can make your declarative UI looks pretty imperative, lets say we want to render an icon if some condition is met:

...
Widget build(BuildContext context) {
  return isEditing ? Icon(Icons.edit) : Container();
}

For these cases we have to return an empty Container if the condition is falsy, because we can not return null if something expects a Widget. Looks simple, but this is something you will be doing a lot, would be good to have a widget that does the dirty work for us, lets see the same UI using ConditionalBuilder:

...
Widget build(BuildContext context) {
  return ConditionalBuilder(
    condition: isEditing,
    builder: (context) => Icon(Icons.edit),
  );
}

Here we have a declarative UI and we do not have to deal with returning the Container.

Conditionally adding Widgets to list

Lets say we have a Column that displays three widgets:

Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Icon(Icons.edit),
        Icon(Icons.clear),
        Icon(Icons.add),
      ],
    );
}

But then, we have to render the clear Icon if one condition is met, we end up with something like this:

Widget build(BuildContext context) {
  final children = <Widget>[
    Icon(Icons.edit),
  ];

  if (isEditing) {
    children.add(Icon(Icons.clear));
  }

  children.add(Icon(Icons.add));

  return Column(
    children: children,
  );
}

We can turn this into:

Widget build(BuildContext context) {
  return Column(
    children: <Widget>[
      Icon(Icons.edit),
      ConditionalBuilder(
        condition: isEditing,
        builder: (context) => Icon(Icons.clear),
      ),
      Icon(Icons.add),
    ],
  );
}

Be aware that even when you can not see the clear Icon, your list does have 3 (Two icons and an empty Container) widgets instead of 2, take that in mind if you are doing some sort of computation based on the list items, but, you get an more concise, declarative and maintainable code.

Usage

After following the installation guide, you can use this widget as follow:

ConditionalBuilder(
  condition: true,
  builder: (context) {
    return Text('This gets rendered');
  },
 )

ConditionalBuilder(
  condition: false,
  builder: (context) {
    return Text('This does not get rendered, an empty Container will be rendered');
  },
)

ConditionalBuilder(
  condition: false,
  builder: (context) {
    return Text('This does not get rendered, as fallback is not null, it is used to render the fallback widget');
  },
  fallback: (context) {
    return Text('This gets rendered');
  }
)

Libraries

conditional_builder