Material Segmented Control
A material segmented control like the one for iOS, in Material style.
We all know well the Cupertino segmented widget in Flutter. But there is no similar in Material, so I thought, why not to create one.
You can check it out on pub.dev: (see package on pub.dev)
In your pubspec.yaml
, add
dependencies:
material_segmented_control: ^5.0.0
Wherever you want to use this widget, import
import 'package:material_segmented_control/material_segmented_control.dart';
int _currentSelection = 0;
MaterialSegmentedControl(
children: _children,
selectionIndex: _currentSelection,
borderColor: Colors.grey,
selectedColor: Colors.redAccent,
unselectedColor: Colors.white,
selectedTextStyle: TextStyle(color: Colors.white),
unselectedTextStyle: TextStyle(color: Colors.redAccent),
borderWidth: 0.7,
borderRadius: 32.0,
disabledChildren: [3],
onSegmentTapped: (index) {
setState(() {
_currentSelection = index;
});
},
);
Map<int, Widget> _children = {
0: Text('Hummingbird'),
1: Text('Kiwi'),
2: Text('Rio'),
3: Text('Telluraves')
};
selectionIndex
to null
. It un-selects all options.onPressed
to null on a button) by setting disabledChildren
. Give it a list with all indices that should be disabled. Give it either null or an empty list to not use the disabled feature.You might want to check out the example project.
Run this command:
With Flutter:
$ flutter pub add material_segmented_control
This will add a line like this to your package's pubspec.yaml (and run an implicit flutter pub get
):
dependencies:
material_segmented_control: ^5.0.0
Alternatively, your editor might support flutter pub get
. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:material_segmented_control/material_segmented_control.dart';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:material_segmented_control/material_segmented_control.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int? _currentSelection = 0;
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
useMaterial3: true,
),
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
MaterialSegmentedControl(
children: _children,
selectionIndex: _currentSelection,
borderColor: Colors.grey,
selectedColor: Colors.redAccent,
unselectedColor: Colors.white,
selectedTextStyle: TextStyle(color: Colors.white),
unselectedTextStyle: TextStyle(color: Colors.redAccent),
borderWidth: 0.7,
borderRadius: 6.0,
disabledChildren: _disabledIndices,
verticalOffset: 8.0,
onSegmentTapped: (index) {
setState(() {
_currentSelection = index;
});
},
),
SizedBox(
height: 8,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
child: Text('Toggle disabled'),
onPressed: () {
// This is just an example on how disabled children work.
// A disabled index is determined randomly.
setState(() {
_disabledIndices.clear();
_disabledIndices.add(_randomInt());
});
},
),
const SizedBox(width: 8),
ElevatedButton(
child: Text('Un-select all'),
onPressed: () => setState(() => _currentSelection = null),
),
],
),
],
),
),
),
);
}
Map<int, Widget> _children = {
0: Text('Flutter'),
1: Text('Dart'),
2: Text('Desktop'),
3: Text('Mobile'),
4: Text('Web')
};
// Holds all indices of children to be disabled.
// Set this list either null or empty to have no children disabled.
List<int> _disabledIndices = [];
int _randomInt() {
return Random.secure().nextInt(_children.length);
}
}
Download details:
Author: benjamin-kraatz
Source: https://github.com/benjamin-kraatz/material_segmented_control