Wrap Widget & Chip Widgets in Flutter

Jamie
4 min readMar 20, 2020

Wrap widget is such a useful widget in many circumstances.

Here we will learn about different types of Chip Widgets such as

  1. Action
  2. Input
  3. Filter
  4. Choice

& Wrap Widgets

Watch Video Tutorial

Wrap Widgets and Chips in Flutter

First Let’s create a simple Chip Widget.

Widget chip(String label, Color color) {
return Chip(
labelPadding: EdgeInsets.all(5.0),
avatar: CircleAvatar(
backgroundColor: Colors.grey.shade600,
child: Text(label[0].toUpperCase()),
),
label: Text(
label,
style: TextStyle(
color: Colors.white,
),
),
backgroundColor: color,
elevation: 6.0,
shadowColor: Colors.grey[60],
padding: EdgeInsets.all(6.0),
);
}

The above code creates a Chip widget and you can add it to the UI as you want.

If we add some more chips inside a row…then this happens…

If we want just scroll, then we can add a ScrollView like this

SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: rowChips(),
),

But wrapping to next line may be your requirement…

Here comes the Wrap Widgets.

Wrap Widget

wrapWidget() {
return Wrap(
spacing: 6.0,
runSpacing: 6.0,
children: <Widget>[
chip('Health', Color(0xFFff8a65)),
chip('Food', Color(0xFF4fc3f7)),
chip('Lifestyle', Color(0xFF9575cd)),
chip('Sports', Color(0xFF4db6ac)),
chip('Nature', Color(0xFF5cda65)),
chip('Learn', Color(0xFFacbb65)),
],
);
}

If you add a wrap widget around the Chips, then it will be properly wrapped to the next line like in the screenshot below.

Wrap Widgets

Chips has some properties out of which one of the important one is the ‘onDelete’ callback.

Let’s take an example of adding the Chips dynamically.

List<String> _dynamicChips; = ['Health', 'Food', 'Nature'];

dynamicChips() {
return Wrap(
spacing: 6.0,
runSpacing: 6.0,
children: List<Widget>.generate(_dynamicChips.length, (int index) {
return Chip(
label: Text(_dynamicChips[index]),
onDeleted: () {
setState(() {
_dynamicChips.removeAt(index);
});
},
);
}),
);
}

Action Chips

These are for executing an action, so these chips won’t have the onDelete callback, instead they will have the ‘onPressed’ callback where you can execute the action when the Chip is tapped.

Widget actionChips() {
return ActionChip(
elevation: 6.0,
padding: EdgeInsets.all(2.0),
avatar: CircleAvatar(
backgroundColor: Colors.green[60],
child: Icon(Icons.call),
),
label: Text('Call'),
onPressed: () {
_key.currentState.showSnackBar(SnackBar(
content: Text('Calling...'),
));
},
backgroundColor: Colors.white,
shape: StadiumBorder(
side: BorderSide(
width: 1,
color: Colors.blueAccent,
)),
);
}

Input Chips

These are basically to represent a Person or an Entity.

Flutter Input Chips
Widget inputChips() {
return InputChip(
padding: EdgeInsets.all(2.0),
avatar: CircleAvatar(
backgroundColor: Colors.blue.shade600,
child: Text('JW'),
),
label: Text('James Watson'),
selected: _isSelected,
selectedColor: Colors.green,
onSelected: (bool selected) {
setState(() {
_isSelected = selected;
});
},
// onPressed: () {
// //
// },
onDeleted: () {
//
},
);
}

This will have ‘onSelected’, ‘onPressed’ and ‘onDeleted’ callbacks.

The main thing to note is that the ‘onPressed’ and ‘onSelected’ cannot be used at the same time.

Filter Chips

This helps to filter some values from a bunch of chips.

Flutter Filter Chips
List<Company> _companies = <Company>[
const Company('Google'),
const Company('Apple'),
const Company('Microsoft'),
const Company('Sony'),
const Company('Amazon'),
];

Iterable<Widget> get companyWidgets sync* {
for (Company company in _companies) {
yield Padding(
padding: const EdgeInsets.all(6.0),
child: FilterChip(
avatar: CircleAvatar(
child: Text(company.name[0].toUpperCase()),
),
label: Text(company.name),
selected: _filters.contains(company.name),
onSelected: (bool selected) {
setState(() {
if (selected) {
_filters.add(company.name);
} else {
_filters.removeWhere((String name) {
return name == company.name;
});
}
});
},
),
);
}

class Company {
const Company(this.name);
final String name;
}

Choice Chips

Flutter Choice Chips

This helps to create a list of Chips to Select from one at a time.

Widget choiceChips() {
return Expanded(
child: ListView.builder(
itemCount: _choices.length,
itemBuilder: (BuildContext context, int index) {
return ChoiceChip(
label: Text(_choices[index]),
selected: _defaultChoiceIndex == index,
selectedColor: Colors.green,
onSelected: (bool selected) {
setState(() {
_defaultChoiceIndex = selected ? index : 0;
});
},
backgroundColor: Colors.blue,
labelStyle: TextStyle(color: Colors.white),
);
},
),
);
}

Please let me know your comments below this post.

Thanks for reading.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Jamie
Jamie

Written by Jamie

Flutter, React Native, Android, iOS App developer.

No responses yet

Write a response