CupertinoSegmentedControl doesn't have a starting value field. How can I initialize? (Flutter; ios)

937

Solution 1

If you would like the CupertinoSegmentedControl widget to be initialised with a starting value, then you could use the groupValue parameter of the CupertinoSegmentedControl widget as per the below example:

import 'package:flutter/cupertino.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _choiceType;

  final _choiceTypes = <int, Widget>{
    1: Text('1'),
    2: Text('2'),
    3: Text('3'),
  };

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      child: SafeArea(
        child: SizedBox(
          width: double.infinity,
          child: Padding(
            padding: EdgeInsets.only(top: 8),
            child: CupertinoSegmentedControl<int>(
              children: _choiceTypes,
              onValueChanged: (value) {
                setState(() {
                  _choiceType = value;
                });
              },
              groupValue: _choiceType,
            ),
          ),
        ),
      ),
    );
  }
}

The documentation here and here gives more information regarding how to use the groupValue parameter and the onValueChanged parameter respectively.

If you would like the selected segment to be stored in state throughout the lifetime of the application and not just for this page, then you could use the provider package to keep track of the selected segment.

Solution 2

Test this sample code and see your response:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

main() {
  runApp(MaterialApp(
    home: TestSegmentedControl(),
  ));
}

class TestSegmentedControl extends StatefulWidget {
  @override
  _TestSegmentedControlState createState() => _TestSegmentedControlState();
}

class _TestSegmentedControlState extends State<TestSegmentedControl> {
  static const _choice_types = {
    0: Text('Test 0'),
    1: Text('Test 1'),
    2: Text('Test 2'),
    3: Text('Test 3'),
  };

  int _currentChoiceId = 0;
  bool _choiceSelected = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            SizedBox(
                width: double.infinity,
                child: Padding(
                    padding: EdgeInsets.only(top: 8),
                    child: CupertinoSegmentedControl<int>(
                      children: _choice_types,
                      onValueChanged: (int newValue) {
                        _choiceSelected = true;
                        setState(() {
                          _currentChoiceId = newValue;
                        });
                      },
                      groupValue: _currentChoiceId,
                    ))),
            RaisedButton(
              onPressed: () {
                Navigator.push(
                    context, MaterialPageRoute(builder: (ctx) => TestPage()));
              },
              child: Text("Next Page"),
            ),
          ],
        ),
      ),
    );
  }
}

class TestPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Test Page"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text("Go Back"),
        ),
      ),
    );
  }
}
Share:
937
ArthurEKing
Author by

ArthurEKing

Updated on November 24, 2022

Comments

  • ArthurEKing
    ArthurEKing over 1 year

    So I'm using a CupertinoSegmentedControl widget in my Flutter application in order to get the user to select an option. Everything works perfectly except in one situation. If the user selects an option, and leaves that field, then comes BACK, while I DO have their selection saved in the code, it's not being visually represented to the user.

    How can this be done?

    My issue is that this widget doesn't seem to have an initial-value option inside it, so I've looked at other options, and the only thing I can think of is trying to programmatically select the button that the customer chose, as the program is reselecting that option and bringing up the widget.

    Is that even plausible/workable? And if so how might I go about it?

    (The widget as it stands is as follows)

    return SizedBox(
      width: double.infinity,
      child: Padding(
        padding: EdgeInsets.only(top: 8),
        child: CupertinoSegmentedControl<int>(
          children: choice_types,
          onValueChanged: (int newValue) {
            choiceType = newValue;
            choice_selected = true;
          }
        )
      )
    );
    

    Any Suggestions?

  • ArthurEKing
    ArthurEKing almost 4 years
    I'm not sure how to implement that in this particular instance, as you're setting states and navigating to other pages, when that's not part of any of what I'm trying to do. Would you be able to parse down your response any?
  • tnc1997
    tnc1997 almost 4 years
    I have removed the navigation from the code sample and added links to the relevant parts of the documentation. You need to setState in the onValueChanged callback function in order to visually update the groupValue of the CupertinoSegmentedControl widget. You can also use the groupValue parameter to provide an initial value to the CupertinoSegmentedControl widget.
  • ArthurEKing
    ArthurEKing almost 4 years
    Thanks! I actually (accidentally from old code) had 2 places where this code was supposedly utilized, and was changing the wrong one. sigh once I put it in the right place it worked fine!