CupertinoSlidingSegmentedControl doesn't provide a way to update the value programmatically. The only workaround is to update a key, e.g., ValueKey, but doing so would disable the sliding transition, making it less ideal.
CupertinoSlidingSegmentedControl(
padding: EdgeInsets.zero,
thumbColor: ColorAssets.green,
groupValue: selected,
onValueChanged: (value) {
},
children: widget.children.map(
(key, value) => MapEntry(
key,
Container(
height: constraints.maxHeight,
alignment: Alignment.center,
padding: const EdgeInsets.only(bottom: 2),
child: Text(
value,
),
)
),
),
)
You can update CupertinoSlidingSegmentedControl
without messing with keys by using setState
to update the variable you're passing to the groupValue
parameter.
setState(() => selected = /* put your new value here */);
Here's an example with code:
and here's the code. Scroll to the bottom for the relevant portion where you update the segmented control programatically.
// SCROLL TO THE BOTTOM FOR THE RELEVANT PORTION
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
enum Sky { midnight, viridian, cerulean }
Map<Sky, Color> skyColors = <Sky, Color>{
Sky.midnight: const Color(0xff191970),
Sky.viridian: const Color(0xff40826d),
Sky.cerulean: const Color(0xff007ba7),
};
void main() => runApp(const SegmentedControlApp());
class SegmentedControlApp extends StatelessWidget {
const SegmentedControlApp({super.key});
@override
Widget build(BuildContext context) {
return const CupertinoApp(
theme: CupertinoThemeData(brightness: Brightness.light),
home: SegmentedControlExample(),
);
}
}
class SegmentedControlExample extends StatefulWidget {
const SegmentedControlExample({super.key});
@override
State<SegmentedControlExample> createState() =>
_SegmentedControlExampleState();
}
class _SegmentedControlExampleState extends State<SegmentedControlExample> {
Sky _selectedSegment = Sky.midnight;
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
backgroundColor: skyColors[_selectedSegment],
navigationBar: CupertinoNavigationBar(
// This Cupertino segmented control has the enum "Sky" as the type.
middle: CupertinoSlidingSegmentedControl<Sky>(
backgroundColor: CupertinoColors.systemGrey2,
thumbColor: skyColors[_selectedSegment]!,
// This represents the currently selected segmented control.
groupValue: _selectedSegment,
// Callback that sets the selected segmented control.
onValueChanged: (Sky? value) {
if (value != null) {
setState(() {
_selectedSegment = value;
});
}
},
children: const <Sky, Widget>{
Sky.midnight: Padding(
padding: EdgeInsets.symmetric(horizontal: 20),
child: Text(
'Midnight',
style: TextStyle(color: CupertinoColors.white),
),
),
Sky.viridian: Padding(
padding: EdgeInsets.symmetric(horizontal: 20),
child: Text(
'Viridian',
style: TextStyle(color: CupertinoColors.white),
),
),
Sky.cerulean: Padding(
padding: EdgeInsets.symmetric(horizontal: 20),
child: Text(
'Cerulean',
style: TextStyle(color: CupertinoColors.white),
),
),
},
),
),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Selected Segment: ${_selectedSegment.name}',
style: const TextStyle(color: CupertinoColors.white),
),
SizedBox(height: 15),
ElevatedButton(
// Update the segmented control programatically here!
onPressed: () => setState(() => _selectedSegment = Sky.cerulean),
child: Text('Update Programatically to Cerulean'),
),
],
),
),
);
}
}