如何在 Flutter 中创建同时具有 kg 和 lbs 选项的 Cupertino 选择器

Posted

技术标签:

【中文标题】如何在 Flutter 中创建同时具有 kg 和 lbs 选项的 Cupertino 选择器【英文标题】:How to create Cupertino picker that has both kg and lbs option in Flutter 【发布时间】:2021-12-27 16:10:25 【问题描述】:

我正在尝试创建一个 Cupertino Picker 来显示重量和其他选项,例如 kg 和 lb。我已经尝试过解决。它适用于 "kg" 但我如何显示 "lb" 以及如何在选择 55 kg 并显示相同的 121.245 lb 后获得,反之亦然,因此这两个值应该是等于例如55 kg = 121.254 lb

这是我的代码

// 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',
                  ),
                ],
              ),
            ),

我的结果是

如何获得磅值以及如上所述

预期结果如下

【问题讨论】:

好的,你想同时创建两个选择器吗? 仅在具有 2 个选项的单个选择器中 好的,在单个对话框中应该是 2options(picker) 吗? 没错,我已经解释过了。 抱歉,我不太了解您要归档的内容,您的小部件同时显示两个选择器,您能否指出您面临的问题并查看您想要做什么存档。 【参考方案1】:

你必须确保你正在重建重量CupertinoPicker。为此,首先将_selectedUnits 设为ValueNotifier

final _selectedUnits = ValueNotifier('lbs');

然后将权重CupertinoPicker 包装在ValueListenableBuilder 中,检查_selectedUnits 的值以确定要在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]'),
            );
          ,
        ),
      );
  ),
),

最后,将你单位CupertinoPickeronSelectedItemChanged中的setState调用替换为

_selectedUnits.value = units[index];

【讨论】:

它的工作,但它的出现类似150.0 ValueNotifier&lt;String&gt;#16987(kgs)的somting字符串 而且 lbs 值也没有显示在字段中 确保您使用的是_selectedUnits.value。看来您正在显示通知对象而不是它的字符串值。 如果您仍然遇到问题。请使用屏幕截图和更新后的代码进行更新。 如何像我问的那样自定义缩放滑块(在预期结果中)

以上是关于如何在 Flutter 中创建同时具有 kg 和 lbs 选项的 Cupertino 选择器的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤动中创建具有多行的行

你如何在 Flutter 中创建服务/提供者?

如何在 Flutter 中创建垂直滚动菜单效果

Flutter Cards:如何在 Flutter 中创建自定义卡片小部件

如何在 Flutter 中创建带有底部彩色边框的 AppBar?

Flutter:如何在我的 Style 类中创建构造函数? [复制]