【问题标题】:Flutter Checkbox not changing/updating/working颤振复选框未更改/更新/工作
【发布时间】:2019-11-14 13:22:51
【问题描述】:

我正在尝试学习 Flutter 中的复选框。

问题是,当我想在 Scaffold(body:) 中使用复选框时,它正在工作。但我想在不同的地方使用它,比如 ListView 中的一个项目。

return Center(
    child: Checkbox(
  value: testValue,
  onChanged: (bool value) {
    setState() {
      testValue = value;
    }
  },
));

但它不起作用,更新和改变任何东西。

编辑:我通过将复选框放入 StatefulBuilder 解决了我的问题。感谢@cristianbregant

 return StatefulBuilder(
    builder: (BuildContext context, StateSetter setState) {
  return Center(
    child: CheckboxListTile(
      title: const Text('Animate Slowly'),
      value: _valueCheck,
      onChanged: (bool value) {
        setState(() {
          _valueCheck = value;
        });
      },
      secondary: const Icon(Icons.hourglass_empty),
    ),
  );
});

【问题讨论】:

  • 在 ListView 中,您必须重建所有列表才能看到您的更改
  • 不工作,是否意味着您在控制台中收到错误消息?如果是这样,您可以将其添加到您的问题中
  • 你是说 setState() 吗? @Caffo17
  • 不,只是没有任何反应复选框没有在 ui @Nolence 中更新自身
  • @developer.alp 我更好地解释了我的意思。如果你想要一个复选框列表,你必须跟踪所有的布尔值。您可以通过 List 来实现。在初始状态,该列表充满了错误。在 ListView 的构建中,您拥有列表中单个元素的索引。当你点击一个复选框时,你必须调用 setState((){ _list[index] = !oldValue })。这使您可以使用新值重建列表。如果您需要,我可以在下面发布一个示例。

标签: flutter dart flutter-layout


【解决方案1】:

不妨试试这些:

return Center(
  child: CheckboxListTile(
    title: const Text('Animate Slowly'),
    value: _valueCheck,
    onChanged: (bool value) {
      setState(() {
       _valueCheck = value;
      });
    },
    secondary: const Icon(Icons.hourglass_empty),
  ),
);

请记住,如果您在对话框或bottomsheet 中使用它,则需要将 Checkbox Widget 包装在 Stateful 构建器中,因为状态不会更新。

【讨论】:

  • 非常感谢!我用 StatefulBuilder 尝试过,现在它可以工作了。起初我认为如果我们将小部件放在 StatefulWidget 中,就不需要使用 StatefulBuilder
  • 不客气!也许考虑将我的答案设置为一个! :D
  • 很好的答案!谢谢!
【解决方案2】:

复选框要求您将 ScaffoldMaterial 作为其父级。如果没有其中任何一个,您会收到以下有用的错误消息:

The following assertion was thrown building Checkbox(dirty, state: _CheckboxState#1163b):
No Material widget found.

Checkbox widgets require a Material widget ancestor.
In material design, most widgets are conceptually "printed" on a sheet of material.
In Flutter's material library, that material is represented by the Material widget. It is the Material widget that renders ink splashes, for instance. Because of this, many material library widgets require that there be a Material widget in the tree above them.

一旦你有了一个材质的祖先,你可以将 ListView 作为它的子元素,它应该可以正常显示:

class SettingsPage extends StatefulWidget {
  @override
  _SettingsPageState createState() => _SettingsPageState();
}

class _SettingsPageState extends State<SettingsPage> {
  var _foo = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView(
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Toggle Foo'),
              Checkbox(
                value: _foo,
                onChanged: (bool value) {
                  setState(() => _foo = value);
                },
              ),
            ],
          ),
        ],
      ),
    );
  }
}

【讨论】:

  • 您好,感谢您的详细解答。然而,在我的小部件顶部,我有一个 Scaffold 小部件。简而言之,它就像这个 Scaffold->body:Column->Container->CheckBox 。但我用 StatefulBuilder 解决了我的问题。我也希望 StatefulBuilder 不会成为性能问题。
【解决方案3】:

看来您必须同时使用initStatedispose

请参阅下面的代码示例:

class SettingsOrder extends StatefulWidget {
  @override
  _SettingsOrderState createState() => _SettingsOrderState();
}

class _SettingsOrderState extends State<SettingsOrder> {

  List options = [];
  List<bool> newoptions = [];
  int selectedoption;
  bool checkedstatus;
  bool initialcall;

Future getproductlist(selectedoption, checkedstatus, initialcall) async{

    List updatedlist = [];

    final arguments = ModalRoute.of(context).settings.arguments as Map;
    int itempos = 0;
    options.clear();

    if(initialcall == false){
      for(var item in arguments['options']){
        updatedlist.add({
          'checkbox' : newoptions[itempos]
        });
        itempos++;
      }
    } else {
      for(var item in arguments['options']){
        updatedlist.add({
          'checkbox' : checkedstatus
        });
        newoptions.add(false);
        itempos++;
      }
    }

    setState(() {
      options = updatedlist;
    });
    
  }

  @override
  void initState(){
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {

    getproductlist(0, false, true);

    return Scaffold(
      body: SingleChildScrollView(
        child: Container(
           width: double.infinity,
           child: ListView.builder(
             primary: false,
             shrinkWrap: true,
             itemCount: options.length,
             itemBuilder: (BuildContext context, int index){
              return Container(
                child: Theme(
                  data: ThemeData(
                    unselectedWidgetColor: Colors.grey
                  ),
                  child: CheckboxListTile(
                    controlAffinity: ListTileControlAffinity.trailing,
                    title: Text(options[index]['name']),
                    value: options[index]['checkbox'],
                    onChanged: (newvalue){
                      int indexposition = index;
                      newoptions.removeAt(indexposition);
                      newoptions.insert(indexposition, newvalue);
                      getproductlist(indexposition, newvalue, false);
                    },
                    activeColor: Color.fromRGBO(0, 130, 214, 1),
                    checkColor: Colors.white,
                  ),
                ),
               );
              }
            ),
           ),
          ),
       );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    • 1970-01-01
    • 2021-11-07
    • 2021-12-11
    • 1970-01-01
    • 2014-01-12
    • 2021-11-19
    相关资源
    最近更新 更多