How to create Cupertino picker that has both kg and lbs option in Flutter

Issue

I’m trying to create a Cupertino Picker that will show weight and other option like kg and lb. Ive tried to work it out. It working for "kg" but how can i display for "lb" and also how to get after selecting 55 kg and display same 121.245 lb vice versa so both values should be equal for example 55 kg = 121.254 lb

this is my code

// weight - 22.0 to 227.0 kg

  // weight declarations
  var _selectedWeight = 150;
  var _selectedWeightDecimals = 0;
  var _selectedUnits = "lbs";
  var units = ['kgs', 'lbs'];
  var lbs = [];
  var kgs = []; 

@override
  void initState() {
    

    for (int j = 22; j <= 227; j++) {
      kgs.add(j);
      lbs.add(j * 2.20462);
    }
  }



//Selection dropdown for Kgs and Lbs

            const SizedBox(height: 15),
            const Text(
              'WEIGHT',
              style: TextConstants.feildHeadText,
            ),
            const SizedBox(
              height: 2,
            ),
            Container(
              height: 51,
              width: double.infinity,
              padding: const EdgeInsets.only(left: 10, right: 10),
              decoration: BoxDecoration(
                borderRadius: const BorderRadius.all(Radius.circular(40)),
                border: Border.all(
                  color: Colors.grey,
                  width: 1,
                ),
              ),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  CupertinoButton(
                    onPressed: () {
                      showModalBottomSheet(
                        context: context,
                        builder: (BuildContext context) {
                          return SizedBox(
                            height: 200,
                            child: Row(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Expanded(
                                  child: CupertinoPicker(
                                    itemExtent: 32,
                                    onSelectedItemChanged: (int index) {
                                      if (_formKey.currentState!.validate()) {
                                        const Text(
                                          "Please select Weight",
                                          style: TextStyle(
                                            color: Colors.red,
                                            fontSize: 16,
                                          ),
                                        );
                                      }
                                      setState(
                                        () {
                                          _selectedWeight = kgs[index];
                                        },
                                      );
                                    },
                                    children: List<Widget>.generate(
                                      kgs.length,
                                      (int index) {
                                        return Center(
                                          child: Text(kgs[index].toString()),
                                        );
                                      },
                                    ),
                                  ),
                                ),
                                Expanded(
                                  child: CupertinoPicker(
                                    itemExtent: 32,
                                    onSelectedItemChanged: (int index) {
                                      if (_formKey.currentState!.validate()) {
                                        const Text(
                                          "Please select Units",
                                          style: TextStyle(
                                            color: Colors.red,
                                            fontSize: 16,
                                          ),
                                        );
                                      }
                                      setState(
                                        () {
                                          _selectedUnits = units[index];
                                        },
                                      );
                                    },
                                    children: List<Widget>.generate(
                                      units.length,
                                      (int index) {
                                        return Center(
                                          child: Text(units[index]),
                                        );
                                      },
                                    ),
                                  ),
                                ),
                              ],
                            ),
                          );
                        },
                      );
                    },
                    child: Text(
                      '$_selectedWeight.$_selectedWeightDecimals  $_selectedUnits',
                      style: const TextStyle(
                        height: 1,
                        color: Colors.black,
                        fontSize: 16,
                      ),
                    ),
                  ),
                  SvgPicture.asset(
                    'assets/icons/dropdown.svg',
                  ),
                ],
              ),
            ),

and my results are
kgs cupertino picker

how to get lbs values and as discribed above

expected result as below

expected

Solution

You have to ensure that you are rebuilding the weight CupertinoPicker. To do so, first, make _selectedUnits a ValueNotifier.

final _selectedUnits = ValueNotifier('lbs');

Then wrap the weight CupertinoPicker in a ValueListenableBuilder, checking the value of _selectedUnits to determine which values to display in the lis.

Expanded(
  child: ValueListenableBuilder<String>(
    valueListenable: _selectedUnits,
    builder: (context, selectedUnits, _) {
      return CupertinoPicker(
        itemExtent: 32,
        onSelectedItemChanged: (int index) {
          if (_formKey.currentState!.validate()) {
            const Text("Please select Weight",
              style: TextStyle(
                color: Colors.red,
                fontSize: 16,
              ),
            );
          }
          setState(
            () {
              if (selectedUnits == 'Kgs') {
                _selectedWeight = kgs[index];
              } else {
              _selectedWeight = lbs[index];
             },
            },
          );
        },
        children: List<Widget>.generate(
          kgs.length,
          (int index) {
            return Center(
              child: Text(
                '${selectedUnits == 'kgs' ? kgs[index] : lbs[index]}'),
            );
          },
        ),
      );
  }),
),

Finally, replace the setState call in your unit CupertinoPicker‘s onSelectedItemChanged with

_selectedUnits.value = units[index];

Answered By – Lee3

Answer Checked By – Willingham (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *