Have you ever been on an e-commerce platform and stumbled across a button that allowed you to select from multiple clothing sizes like S, XS, M, L, XL, or XXL?
It is an efficient way to present various options without cluttering the interface. If you have ever wondered how you can implement a similar feature in your Flutter app, I have good news for you—it can be achieved using a SegmentedButton.
Segmented buttons are particularly useful in cases where users need to navigate between different fragments or sections of your app, or when they need to sort elements. These buttons offer a compact and visually appealing solution for presenting 2-5 options.
In Flutter, creating a SegmentedButton is straightforward and customizable, allowing for a seamless experience both on the development side and for the end-user. This widget is a versatile tool in your UI kit, enhancing the way people select options.
Let's learn this functionality and see how we can bring this into our Flutter applications.
To correctly implement a SegmentedButton in Flutter, you should ensure that your widget and its properties are correctly set. Below is the correct implementation for a simple segmented button setup that allows a single selection:
1import 'package:flutter/material.dart'; 2 3void main() => runApp(MyApp()); 4 5class MyApp extends StatelessWidget { 6 7 Widget build(BuildContext context) { 8 return MaterialApp( 9 home: Scaffold( 10 appBar: AppBar(title: Text('Simple Segmented Button Example')), 11 body: Center( 12 child: SimpleSegmentedControl() 13 ) 14 ), 15 ); 16 } 17} 18 19class SimpleSegmentedControl extends StatefulWidget { 20 21 _SimpleSegmentedControlState createState() => _SimpleSegmentedControlState(); 22} 23 24class _SimpleSegmentedControlState extends State<SimpleSegmentedControl> { 25 int _selectedIndex = 0; 26 final List<String> _options = ['One', 'Two', 'Three', 'Four']; 27 28 29 Widget build(BuildContext context) { 30 return Column( 31 mainAxisAlignment: MainAxisAlignment.center, 32 children: [ 33 ToggleButtons( 34 isSelected: List.generate(_options.length, (index) => index == _selectedIndex), 35 onPressed: (int index) { 36 setState(() { 37 _selectedIndex = index; 38 }); 39 }, 40 children: _options.map((String label) => Text(label)).toList(), 41 ), 42 Padding( 43 padding: EdgeInsets.all(16.0), 44 child: Text('Selected: ${_options[_selectedIndex]}'), 45 ), 46 ], 47 ); 48 } 49}
This example will use the CupertinoSegmentedControl from the flutter/cupertino.dart package to create a segmented control with the segments labeled "One", "Two", "Three", and "Four".
To customize the appearance of your segmented buttons, Flutter provides several styling options. You can adjust the border color, background color, and text style of each segment.
Here you can also use the 'SegmentedButton.styleFrom' method provided by Flutter.
1ToggleButtons( 2 borderColor: Colors.deepPurple, 3 selectedBorderColor: Colors.deepPurpleAccent, 4 borderWidth: 2, 5 selectedColor: Colors.white, 6 color: Colors.deepPurple, 7 fillColor: Colors.deepPurple.shade100, 8 borderRadius: BorderRadius.circular(20), 9 children: _options.map((String label) => Padding( 10 padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), 11 child: Text(label), 12 )).toList(), 13 onPressed: (int index) { 14 setState(() { 15 _selectedIndex = index; 16 }); 17 }, 18 isSelected: List.generate(_options.length, (index) => index == _selectedIndex), 19 )
For applications requiring more complex state management, such as when multiple segments can be selected, you need to set the multiSelectionEnabled property to true. This allows users to select more than one option at a time. Here’s how to implement it:
1class MultiSelectSegmentedControl extends StatefulWidget { 2 3 _MultiSelectSegmentedControlState createState() => _MultiSelectSegmentedControlState(); 4} 5 6class _MultiSelectSegmentedControlState extends State<MultiSelectSegmentedControl> { 7 final List<String> _options = ['One', 'Two', 'Three', 'Four']; 8 List<bool> _isSelected = [false, false, false, false]; 9 10 11 Widget build(BuildContext context) { 12 return Column( 13 mainAxisAlignment: MainAxisAlignment.center, 14 children: [ 15 ToggleButtons( 16 borderColor: Colors.deepPurple, 17 selectedBorderColor: Colors.deepPurpleAccent, 18 borderWidth: 2, 19 selectedColor: Colors.white, 20 color: Colors.deepPurple, 21 fillColor: Colors.deepPurple.shade100, 22 borderRadius: BorderRadius.circular(20), 23 children: _options.map((String label) => Padding( 24 padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), 25 child: Text(label), 26 )).toList(), 27 onPressed: (int index) { 28 setState(() { 29 _isSelected[index] = !_isSelected[index]; 30 }); 31 }, 32 isSelected: _isSelected, 33 ), 34 SizedBox(height: 20), 35 Text('Selected: ' + _isSelected.asMap().entries.where((entry) => entry.value).map((entry) => _options[entry.key]).join(', '), 36 style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.deepPurple)), 37 ], 38 ); 39 } 40}
Segmented buttons are particularly useful for sorting elements within your Flutter application. By associating each segment with a sorting condition, you can dynamically adjust the displayed data based on the user's selection. Here's an example to illustrate sorting functionality:
1class MyApp extends StatelessWidget { 2 3 Widget build(BuildContext context) { 4 return MaterialApp( 5 home: Scaffold( 6 appBar: AppBar(title: Text('Sorting with Segmented Buttons')), 7 body: Center( 8 child: SortingSegmentedControl() 9 ), 10 ), 11 ); 12 } 13} 14 15class SortingSegmentedControl extends StatefulWidget { 16 17 _SortingSegmentedControlState createState() => _SortingSegmentedControlState(); 18} 19 20class _SortingSegmentedControlState extends State<SortingSegmentedControl> { 21 List<String> _items = ['Orange', 'Apple', 'Banana', 'Mango']; 22 List<bool> _isSelected = [true, false, false]; 23 24 void _sortItems(int index) { 25 setState(() { 26 for (int buttonIndex = 0; buttonIndex < _isSelected.length; buttonIndex++) { 27 if (buttonIndex == index) { 28 _isSelected[buttonIndex] = true; 29 } else { 30 _isSelected[buttonIndex] = false; 31 } 32 } 33 34 if (index == 0) { 35 _items.sort((a, b) => a.compareTo(b)); // Alphabetical A-Z 36 } else if (index == 1) { 37 _items.sort((a, b) => b.compareTo(a)); // Reverse Alphabetical Z-A 38 } else if (index == 2) { 39 _items.shuffle(); // Random order 40 } 41 }); 42 } 43 44 45 Widget build(BuildContext context) { 46 return Column( 47 mainAxisAlignment: MainAxisAlignment.center, 48 children: <Widget>[ 49 ToggleButtons( 50 borderColor: Colors.blue, 51 selectedBorderColor: Colors.blueAccent, 52 borderWidth: 2, 53 selectedColor: Colors.white, 54 color: Colors.blue, 55 fillColor: Colors.lightBlue.shade100, 56 borderRadius: BorderRadius.circular(10), 57 children: <Widget>[ 58 Padding(padding: EdgeInsets.symmetric(horizontal: 16), child: Text('A-Z')), 59 Padding(padding: EdgeInsets.symmetric(horizontal: 16), child: Text('Z-A')), 60 Padding(padding: EdgeInsets.symmetric(horizontal: 16), child: Text('Random')), 61 ], 62 onPressed: (int index) { 63 _sortItems(index); 64 }, 65 isSelected: _isSelected, 66 ), 67 Expanded( 68 child: ListView.builder( 69 itemCount: _items.length, 70 itemBuilder: (context, index) => ListTile( 71 title: Text(_items[index]), 72 ), 73 ), 74 ), 75 ], 76 ); 77 } 78}
Flutter’s segmented buttons can be used in more advanced scenarios beyond simple selection tasks. They can be integrated into larger applications for more complex functionalities such as controlling a multi-panel layout or as part of a form where choices affect other components. For instance, you could use segmented buttons to switch views within a page dynamically:
1class ViewSwitcher extends StatefulWidget { 2 3 _ViewSwitcherState createState() => _ViewSwitcherState(); 4} 5 6class _ViewSwitcherState extends State<ViewSwitcher> { 7 int _selectedIndex = 0; 8 9 Widget _getView(int index) { 10 switch (index) { 11 case 0: 12 return Text('Home View'); 13 case 1: 14 return Text('Settings View'); 15 case 2: 16 return Text('Profile View'); 17 default: 18 return Text('Error: Unknown view'); 19 } 20 } 21 22 23 Widget build(BuildContext context) { 24 return Column( 25 children: <Widget>[ 26 ToggleButtons( 27 children: <Widget>[ 28 Icon(Icons.home), 29 Icon(Icons.settings), 30 Icon(Icons.person), 31 ], 32 onPressed: (int index) { 33 setState(() { 34 _selectedIndex = index; 35 }); 36 }, 37 isSelected: List.generate(3, (index) => index == _selectedIndex), 38 ), 39 Expanded(child: _getView(_selectedIndex)) 40 ], 41 ); 42 } 43}
This example demonstrates using segmented buttons to switch between different views within a single screen. The ToggleButtons widget adjusts the state to show different widgets based on the selected index.
When implementing segmented buttons in Flutter, there are several best practices and pitfalls to be aware of:
• Performance: Avoid rebuilding the entire widget tree when the state changes. Use state management solutions like Provider or Bloc to handle state changes efficiently.
• Design Consistency: Ensure that the button’s design aligns with the overall UI theme of your application. Consistent styling is key to a seamless user experience.
• Accessibility: Provide sufficient contrast, touch targets, and labels for accessibility. Flutter’s built-in widgets support accessibility out of the box, but always test with real users or accessibility tools.
• Overuse: While segmented buttons are useful, using them inappropriately (e.g., for long lists of options) can lead to poor user experiences. They are best used for a small number of mutually exclusive choices.
Segmented buttons in Flutter offer a flexible way to present users with a compact set of options. By understanding how to implement, customize, and deploy these widgets effectively, developers can enhance the usability and aesthetics of their applications. Experiment with different styles, interactions, and configurations to discover what works best for your project.
For those looking to deepen their understanding of segmented buttons or explore more complex implementations, the following resources are invaluable:
• Flutter Official Documentation
With these tools and knowledge, you're well-equipped to start integrating segmented buttons into your Flutter applications, enhancing both functionality and user engagement.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.