如何处理在flutter中动态创建的复选框列表?

时间:2017-07-17 20:33:21

标签: flutter

使用flutter,我正在尝试使用一些文本和旁边的自定义复选框构建值列表。点击文本或复选框上的任意位置应显示启用状态,再次点击应禁用它。我不确定如何分别处理每个复选框的状态。我也试过使用CheckBoxListTile,但我不确定如何实现我想要的。有人可以提供任何例子吗?

9 个答案:

答案 0 :(得分:8)

以下是CheckboxListTile的一些示例代码。您可以在gallery中找到更多示例。

screenshot

import 'package:flutter/material.dart';

class Demo extends StatefulWidget {
  @override
  DemoState createState() => new DemoState();
}

class DemoState extends State<Demo> {
  Map<String, bool> values = {
    'foo': true,
    'bar': false,
  };

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(title: new Text('CheckboxListTile demo')),
      body: new ListView(
        children: values.keys.map((String key) {
          return new CheckboxListTile(
            title: new Text(key),
            value: values[key],
            onChanged: (bool value) {
              setState(() {
                values[key] = value;
              });
            },
          );
        }).toList(),
      ),
    );
  }
}

void main() {
  runApp(new MaterialApp(home: new Demo(), debugShowCheckedModeBanner: false));
}

答案 1 :(得分:4)

我认为它将按您的意愿工作。还将所有选定的复选框值存储到List变量中。因此,您只需将此代码放在main.dart文件中,然后执行以检查其工作原理即可。

import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Multi-Select & Unselect Checkbox in Flutter'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List _selecteCategorys = List();

  Map<String, dynamic> _categories = {
    "responseCode": "1",
    "responseText": "List categories.",
    "responseBody": [
      {"category_id": "5", "category_name": "Barber"},
      {"category_id": "3", "category_name": "Carpanter"},
      {"category_id": "7", "category_name": "Cook"}
    ],
    "responseTotalResult":
        3 // Total result is 3 here becasue we have 3 categories in responseBody.
  };

  void _onCategorySelected(bool selected, category_id) {
    if (selected == true) {
      setState(() {
        _selecteCategorys.add(category_id);
      });
    } else {
      setState(() {
        _selecteCategorys.remove(category_id);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: ListView.builder(
          itemCount: _categories['responseTotalResult'],
          itemBuilder: (BuildContext context, int index) {
            return CheckboxListTile(
              value: _selecteCategorys
                  .contains(_categories['responseBody'][index]['category_id']),
              onChanged: (bool selected) {
                _onCategorySelected(selected,
                    _categories['responseBody'][index]['category_id']);
              },
              title: Text(_categories['responseBody'][index]['category_name']),
            );
          }),  
    );
  }
}

答案 2 :(得分:3)

使用列表包含返回布尔值。

这是示例

List<int> selectedList = [];
List<Widget> = mList;
createMenuWidget(Course courses) {
  for (int b = 0; b < courses.length; b++) {
    Map cmap = courses[b];
    mList.add(CheckboxListTile(
      onChanged: (bool value){
        setState(() {
          if(value){
            selectedList.add(cmap[course_id]);
          }else{
            selectedList.remove(cmap[course_id]);
          }
        });
      },
      value: selectedList.contains(cmap[course_id]),
      title: new Text(cmap[course_name]),
    ));
  }
}

答案 3 :(得分:1)

请使用包grouped_buttons。
它同时支持复选框和单选。
https://pub.dartlang.org/packages/grouped_buttons

CheckboxGroup(
      labels: <String>[
        "Sunday",
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday",
      ],
      disabled: [
        "Wednesday",
        "Friday"
      ],
      onChange: (bool isChecked, String label, int index) => print("isChecked: $isChecked   label: $label  index: $index"),
      onSelected: (List<String> checked) => print("checked: ${checked.toString()}"),
    ),

enter image description here

以及此处https://github.com/akshathjain/grouped_buttons/blob/master/example/lib/main.dart

的用法的完整示例

和作者的实现逻辑 https://github.com/akshathjain/grouped_buttons/blob/master/lib/src/checkbox_group.dart

基本上,作者使用两个字符串列表来控制选择和取消选择

void onChanged(bool isChecked, int i){
  bool isAlreadyContained = _selected.contains(widget.labels.elementAt(i));

  if(mounted){
   setState(() {
    if(!isChecked && isAlreadyContained){
      _selected.remove(widget.labels.elementAt(i));
    }else if(isChecked && !isAlreadyContained){
      _selected.add(widget.labels.elementAt(i));
    }

    if(widget.onChange != null) widget.onChange(isChecked, widget.labels.elementAt(i), i);
    if(widget.onSelected != null) widget.onSelected(_selected);
   });
 }
}

答案 4 :(得分:0)

在这里你怎么做

import 'package:flutter/material.dart';

class RegisterFragments extends StatefulWidget {
  RegisterFragments({Key key, this.step}) : super(key: key);
  final int step;

  _RegisterFragmentsState createState() => _RegisterFragmentsState();
}

class _RegisterFragmentsState extends State<RegisterFragments> {
  Map<String, bool> values = {"abc": false, "def": true, "ghi": false};
  List<String> _do = ['One', 'Two', 'Free', 'Four'];
  String _dropdownValue = 'One';

  @override
  Widget build(BuildContext context) {
    switch (widget.step) {
      case 0:
        return buildDo();
        break;
      case 1:
        return Container(
          child: ListView.builder(
            shrinkWrap: true,
            itemCount: values.length,
            itemBuilder: (BuildContext context, int index) {
              switch (widget.step) {
                case 0:
                  return buildDo();
                  break;
                case 1:
                  return buildService(context, index);
                  break;
                default:
                  return Container();
                  break;
              }
            },
          ),
        );
        break;
      default:
        return Container();
        break;
    }
  }

  Widget buildService(BuildContext context, int index) {
    String _key = values.keys.elementAt(index);

    return Container(
      child: Card(
        child: CheckboxListTile(
          title: Text(_key),
          onChanged: (bool value) {
            setState(() {
              values[_key] = value;
            });
          },
          value: values[_key],
        ),
      ),
    );
  }

  Widget buildDo() {
    return DropdownButton<String>(
      isExpanded: true,
      hint: Text("Service"),
      items: _do.map<DropdownMenuItem<String>>((String value) {
        return DropdownMenuItem<String>(
          value: value,
          child: Text(value),
        );
      }).toList(),
      onChanged: (String newValue) {
        setState(() {
          this._dropdownValue = newValue;
        });
      },
      value: _dropdownValue,
    );
  }
}

答案 5 :(得分:0)

使用 chekboxListTile

这是示例代码

    @override
    Widget build(BuildContext context) {
      return Center(
        child: CheckboxListTile(
          title: Text('Check me'),
  );
    }

顺便说一句,您还可以在Flutter的 ListView 中添加复选框。应用示例如下-

Main.dart

import 'package:flutter/material.dart';
import 'checkbox_in_listview_task-7.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(primarySwatch: Colors.blue,
      ),
home: CheckBoxInListview(),
    );
  }
}

checkbox_in_listview_task.dart

import 'package:flutter/material.dart';

class CheckBoxInListview extends StatefulWidget {
  @override
  _CheckBoxInListviewState createState() => _CheckBoxInListviewState();
}

class _CheckBoxInListviewState extends State<CheckBoxInListview> {
  bool _isChecked = true;

  List<String> _texts = [
    "InduceSmile.com," "Flutter.io",
    "google.com",
    "youtube.com",
    "yahoo.com",
    "gmail.com"
  ];
  @override
  Widget build(BuildContext context) {
return Scaffold(
      appBar: AppBar(
        title: Text("CheckBox in ListView Example"),
      ),
      body: ListView(
        padding: EdgeInsets.all(8.0),
        children: _texts.map((text) => CheckboxListTile(
          title: Text(text),
           value: _isChecked,
              onChanged: (val) {
              setState(() {
               _isChecked = val;

            });
          },
        )).toList(),
      ),
    );
  }
}

这是输出

CheckBox in LisView in Flutter app

答案 6 :(得分:0)

如果您正在使用CheckBoxGroup或任何类似的AND并且位于滑块内,请不要忘记将其放在StatefulBuilder中:

    return StatefulBuilder(// StatefulBuilder
    builder: (context, setState) {
  return CheckboxGroup(
    orientation: GroupedButtonsOrientation.HORIZONTAL,
    margin: const EdgeInsets.only(left: 12.0),
    onSelected: (List selected) => setState(() {
      _checked = selected;
    }),
    labels: teamWorkoutDays,
    checked: _checked,
    itemBuilder: (Checkbox cb, Text txt, int i) {
      return Column(
        children: <Widget>[
          Icon(Icons.polymer),
          cb,
          txt,
        ],
      );
    },
  );
});

答案 7 :(得分:0)

使用 CheckBox 的动态数据列表执行此操作的简单方法。

List<String>data= ["Mathew","Deon","Sara","Yeu"];
List<String> userChecked = [];

ListView.builder(
    itemCount: data.length,
    itemBuilder: (context, i) {
      return ListTile(
        title: Text(
            data[i])
        trailing:Checkbox(
                value: userChecked.contains(data[i]),
                onChanged: (val) {
                  _onSelected(val, data[i]);
                },
              )
            //you can use checkboxlistTile too
      );
    })
// now we write the functionality to check and uncheck it!!

void _onSelected(bool selected, String dataName) {
if (selected == true) {
  setState(() {
    userChecked.add(dataName);
  });
} else {
  setState(() {
    userChecked.remove(dataName);
  });
}

}

大功告成!!... 享受飘飘... 竖起大拇指,因为它对你有用!! :P

答案 8 :(得分:0)

屏幕截图(空安全)

enter image description here


代码:

class _MyPageState extends State<MyPage> {
  final Map<String, bool> _map = {};
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () => setState(() => _map.addEntries([MapEntry('Checkbox #${++_count}', false)])),
      ),
      body: ListView(
        children: _map.keys
            .map(
              (key) => CheckboxListTile(
                value: _map[key],
                onChanged: (value) => setState(() => _map[key] = value!),
                subtitle: Text(key),
              ),
            )
            .toList(),
      ),
    );
  }
}