skip to Main Content

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,
            ),
          )
      ),
    ),
  )

2

Answers


  1. Chosen as BEST ANSWER

    Here is the Snippet to achieve toggling CupertinoSegmentedControl programmatically.
    where sliderkey is given to CupertinoSegmentedControl widget.

     void toggle(int index) {
      final x = (sliderKey.currentContext!.findRenderObject() as RenderBox).size.width;
      (sliderKey.currentState as dynamic)?.onTapUp(TapUpDetails(
          kind: PointerDeviceKind.touch,
          localPosition: Offset(index * (x / (widget.children.length)), (widget.children.length + 1))));
    }
    

  2. 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:

    Screen recording of result

    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'),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search