没有选择芯片时如何禁用按钮?

How do I disable a button when no chip is selected?

This is the interface that I made 我需要做的是在没有选择芯片时禁用“Select”按钮,但我是 flutter 的新手,我仍然对如何处理这个逻辑感到困惑。有什么办法吗?

这是我使用的代码:

import 'package:flutter/material.dart';


class ChipDemo extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _ChipDemoState();
}

class _ChipDemoState extends State<ChipDemo> {
  late GlobalKey<ScaffoldState> _key;
  late bool _isSelected;
  late List<FilterWidget> _status;
  late List<FilterWidget> _projectCode;
  late List<FilterWidget> _labor;
  late List<String> _statusFilters;
  late List<String> _projectCodeFilters;
  late List<String> _laborFilters;
  String pickedStartDate = 'Pick the start date';
  String pickedEndDate = 'Pick the end date';
  DateTime selectedStartDate = DateTime.now();
  DateTime selectedEndDate = DateTime.now();
   DateTime ? startDate;
  DateTime ? endDate;

  @override
  void initState() {
    super.initState();
    _key = GlobalKey<ScaffoldState>();
    _isSelected = false;
    _statusFilters = <String>[];
    _projectCodeFilters = <String>[];
    _laborFilters = <String>[];
    _status = <FilterWidget>[
      FilterWidget('WAPPR'),
      FilterWidget('APPR'),
    ];
    _projectCode = <FilterWidget>[
      FilterWidget('PRO-101'),
      FilterWidget('PRO-102'),
      FilterWidget('PRO-103'),
      FilterWidget('PRO-104'),
      FilterWidget('PRO-105'),
      FilterWidget('PRO-106'),
      FilterWidget('PRO-107'),
      FilterWidget('PRO-108'),
    ];
    _labor = <FilterWidget>[
      FilterWidget('Bimo'),
      FilterWidget('Raka'),
      FilterWidget('Juan'),
      FilterWidget('Panji'),
      FilterWidget('Septa'),
      FilterWidget('Rifaldi'),
      FilterWidget('Hansen'),
      FilterWidget('Satrio'),
    ];
  }

  String getStartDateText(){
    if (startDate == null){
      return 'Select Date';
    }else {
      return '${startDate!.month}/${startDate!.day}/${startDate!.year}';
    }
  }

  String getEndDateText(){
    if (endDate == null){
      return 'Select Date';
    }else {
      return '${endDate!.month}/${endDate!.day}/${endDate!.year}';
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _key,
      appBar: AppBar(
        title: const Text("My Team",
          style: TextStyle(
            fontSize: 18,
            color: Colors.black,
        ),
        ),
        backgroundColor: Colors.white,
        centerTitle: true,
        automaticallyImplyLeading: false,
      ),
      body: SingleChildScrollView(
      child: Padding(
          padding: EdgeInsets.all(15),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            const Text('Status',
              style: TextStyle(
                fontSize: 18,
                color: Colors.black,
                fontWeight: FontWeight.w500,
                fontFamily: "Roboto",
              ),
            ),
            Wrap(
              children: statusPosition.toList(),
            ),
            const SizedBox(
              height: 10,
            ),
            Row(
              children: [
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.start,
                  children:[
           const Text('Start Date',
              style: TextStyle(
                fontSize: 18,
                color: Colors.black,
                fontWeight: FontWeight.w500,
                fontFamily: "Roboto",
              ),
            ),
                    OutlinedButton(
                        onPressed: () {
                          _selectStartDate(context);
                        },
                        style: OutlinedButton.styleFrom(
                          side: BorderSide(width: 1.0, color: Colors.grey),
                        ),
                        child: Text(getStartDateText(),
                          style: TextStyle(color: Colors.grey),
                        ),
                    ),
              ],
                ),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.start,
                  children:[
                    const Text('End Date',
                  style: TextStyle(
                    fontSize: 18,
                    color: Colors.black,
                    fontWeight: FontWeight.w500,
                    fontFamily: "Roboto",
                  ),
                ),
                    OutlinedButton(
                      onPressed: () {
                        _selectEndDate(context);
                      },
                      style: OutlinedButton.styleFrom(
                        side: BorderSide(width: 1.0, color: Colors.grey),
                      ),
                      child: Text(getEndDateText(),
                        style: TextStyle(color: Colors.grey),
                      ),
                    ),
                ],
                ),
            ],
            ),
            const SizedBox(
              height: 10,
            ),
            const Text('Project Code',
              style: TextStyle(
                fontSize: 18,
                color: Colors.black,
                  fontWeight: FontWeight.w500,
                fontFamily: "Roboto",
              ),
            ),
            Wrap(
              children: projectCodePosition.toList(),
            ),
            Row(
            children: [
              SizedBox.fromSize(),
              Spacer(),
              Container(
                height: 50 ,
                  width: 150 ,
                  padding: EdgeInsets.only(right:15),
              child: ElevatedButton(
              style: ButtonStyle(
                  backgroundColor: MaterialStateProperty.all(Color(0xFF023E8A)),
                  shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                      RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0),
                      )
                  )
              ),
              onPressed:  () async {

              },
              child: Text('Select', style: TextStyle(color: Colors.white, fontWeight: FontWeight.w700, fontFamily: "Roboto", fontSize: 16.0,)),
              ),
              ),
            ],
            ),
            const Text('Labor',
              style: TextStyle(
                fontSize: 18,
                color: Colors.black,
                fontWeight: FontWeight.w500,
                fontFamily: "Roboto",
              ),
            ),
            Wrap(
              children: laborPosition.toList(),
            ),
          ],
        )
        ),
      ),
      bottomNavigationBar: Card(
        child : Container(
          padding: EdgeInsets.all(12.0),
          height: 86,
          decoration: const BoxDecoration(
            color: Colors.white,
            boxShadow: <BoxShadow>[
              BoxShadow(
                color: Colors.black54,
                blurRadius: 20.0,
                spreadRadius: -20.0,
                offset: Offset(0.0, -15.0),
              )
            ],
          ),
          child: ElevatedButton(
            style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(Color(0xFF023E8A)),
                shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                    RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0),
                    )
                )
            ),
            onPressed:  () async {

            },
            child: Text('Search', style: TextStyle(color: Colors.white, fontWeight: FontWeight.w700, fontFamily: "Roboto", fontSize: 16.0,)),
          ),
        ),
      ),
    );
  }
  Future _selectStartDate(BuildContext context) async {
    final newDate = await showDatePicker(
      context: context,
      initialDate: selectedStartDate,
      firstDate: DateTime(2010),
      lastDate: DateTime(2025),
    );
    if (newDate == null) return;
    setState(() => startDate = newDate);
  }
  _selectEndDate(BuildContext context) async {
    final newDate = await showDatePicker(
      context: context,
      initialDate: selectedEndDate,
      firstDate: DateTime(2010),
      lastDate: DateTime(2025),
    );
    if (newDate == null) return;
    setState(() => endDate = newDate);
  }



  Iterable<Widget> get statusPosition sync* {
    for (FilterWidget company in _status) {
      yield Padding(
        padding: const EdgeInsets.all(6.0),
        child: FilterChip(
          backgroundColor: Colors.white,
          shape: StadiumBorder(
            side: BorderSide(color: Colors.grey, width: 0.5),
          ),
          avatar: CircleAvatar(
            backgroundColor: Colors.cyan,
            child: Text(
              company.name[0].toUpperCase(),
              style: TextStyle(color: Colors.white),
            ),
          ),
          label: Text(
            company.name,
            style: TextStyle(color: _isSelected == false ? Colors.grey : Colors.white,
              fontFamily: "Roboto",
            ),
          ),
          selected: _statusFilters.contains(company.name),
          checkmarkColor: Colors.white,
          selectedColor: Color(0xFF023E8A),
          onSelected: (bool selected) {
            setState(() {
              if (selected) {
                _statusFilters.add(company.name);
              } else {
                _statusFilters.removeWhere((String name) {
                  return name == company.name;
                });
              }

              print(_statusFilters.toString());
            });
          },
        ),
      );
    }
  }

  Iterable<Widget> get projectCodePosition sync* {
    for (FilterWidget company in _projectCode) {
      yield Padding(
        padding: const EdgeInsets.all(6.0),
        child: FilterChip(
          backgroundColor: Colors.white,
          shape: StadiumBorder(
            side: BorderSide(color: Colors.grey, width: 0.5),
          ),
          label: Text(
            company.name,
            style: TextStyle(color: _isSelected == false ? Colors.grey : Colors.white,
                fontFamily: "Roboto",
            ),
          ),
          selected: _projectCodeFilters.contains(company.name),
          checkmarkColor: Colors.white,
          selectedColor: Color(0xFF023E8A),
          onSelected: (bool selected) {
            setState(() {
              if (selected) {
                _projectCodeFilters.add(company.name);
              } else {
                _projectCodeFilters.removeWhere((String name) {
                  return name == company.name;
                });
              }

              print(_projectCodeFilters.toString());
            });
          },
        ),
      );
    }
  }

  Iterable<Widget> get laborPosition sync* {
    for (FilterWidget company in _labor) {
      yield Padding(
        padding: const EdgeInsets.all(6.0),
        child: FilterChip(
          backgroundColor: Colors.white60,
          shape: StadiumBorder(
            side: BorderSide(color: Colors.grey, width: 0.5),
          ),
          avatar: CircleAvatar(
            backgroundColor: Colors.cyan,
            child: Text(
              company.name[0].toUpperCase(),
              style: TextStyle(color: Colors.white),
            ),
          ),
          label: Text(
            company.name,
            style: TextStyle(color: Colors.grey,
              fontFamily: "Roboto", ),
          ),
          selected: _laborFilters.contains(company.name),
          selectedColor: Color(0xFF023E8A),
          onSelected: (bool selected) {
            setState(() {
              if (selected) {
                _laborFilters.add(company.name);
              } else {
                _laborFilters.removeWhere((String name) {
                  return name == company.name;
                });
              }

              print(_laborFilters.toString());
            });
          },
        ),
      );
    }
  }
}

class FilterWidget {
  const FilterWidget(this.name);
  final String name;
}

................................................ ..................................................... ......

将芯片点击添加到空列表,然后检查列表是否为空...

声明一个名为 activateButton 的 bool,只要选择了筹码就将其设置为 true,并且只要未选择任何筹码,检查 _projectCodeFilters 数组的长度,如果它 returns 到原来的长度,然后什么都不选。 另外,我操作了onPress函数,当你的flag为FALSE时,你什么都不用做,而且当flag为FALSE时,按钮颜色为灰色。

P.S 我在 dartpad 上操作了代码,所以我删除了 null saftey,只是重新检查是否为 null。

import 'package:flutter/material.dart';

void main() {
  // any preprocessing can be done here, such as determining a device location
  //
  // runApp is a Flutter function that runs your Flutter app
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Welcome to Flutter'),
        ),
        body: ChipDemo(),
      ),
    );
  }
}

class ChipDemo extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _ChipDemoState();
}

class _ChipDemoState extends State<ChipDemo> {
  GlobalKey<ScaffoldState> _key;
  bool _isSelected;
  List<FilterWidget> _status;
  List<FilterWidget> _projectCode;
  List<FilterWidget> _labor;
  List<String> _statusFilters;
  List<String> _projectCodeFilters;
  List<String> _laborFilters;
  String pickedStartDate = 'Pick the start date';
  String pickedEndDate = 'Pick the end date';
  DateTime selectedStartDate = DateTime.now();
  DateTime selectedEndDate = DateTime.now();
  DateTime startDate;
  DateTime endDate;
  bool activateButton = false;
  @override
  void initState() {
    super.initState();
    _key = GlobalKey<ScaffoldState>();
    _isSelected = false;
    _statusFilters = <String>[];
    _projectCodeFilters = <String>[];
    _laborFilters = <String>[];
    _status = <FilterWidget>[
      FilterWidget('WAPPR'),
      FilterWidget('APPR'),
    ];
    _projectCode = <FilterWidget>[
      FilterWidget('PRO-101'),
      FilterWidget('PRO-102'),
      FilterWidget('PRO-103'),
      FilterWidget('PRO-104'),
      FilterWidget('PRO-105'),
      FilterWidget('PRO-106'),
      FilterWidget('PRO-107'),
      FilterWidget('PRO-108'),
    ];
    _labor = <FilterWidget>[
      FilterWidget('Bimo'),
      FilterWidget('Raka'),
      FilterWidget('Juan'),
      FilterWidget('Panji'),
      FilterWidget('Septa'),
      FilterWidget('Rifaldi'),
      FilterWidget('Hansen'),
      FilterWidget('Satrio'),
    ];
  }

  String getStartDateText() {
    if (startDate == null) {
      return 'Select Date';
    } else {
      return '${startDate.month}/${startDate.day}/${startDate.year}';
    }
  }

  String getEndDateText() {
    if (endDate == null) {
      return 'Select Date';
    } else {
      return '${endDate.month}/${endDate.day}/${endDate.year}';
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _key,
      appBar: AppBar(
        title: const Text(
          "My Team",
          style: TextStyle(
            fontSize: 18,
            color: Colors.black,
          ),
        ),
        backgroundColor: Colors.white,
        centerTitle: true,
        automaticallyImplyLeading: false,
      ),
      body: SingleChildScrollView(
        child: Padding(
            padding: EdgeInsets.all(15),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                const Text(
                  'Status',
                  style: TextStyle(
                    fontSize: 18,
                    color: Colors.black,
                    fontWeight: FontWeight.w500,
                    fontFamily: "Roboto",
                  ),
                ),
                Wrap(
                  children: statusPosition.toList(),
                ),
                const SizedBox(
                  height: 10,
                ),
                Row(
                  children: [
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: [
                        const Text(
                          'Start Date',
                          style: TextStyle(
                            fontSize: 18,
                            color: Colors.black,
                            fontWeight: FontWeight.w500,
                            fontFamily: "Roboto",
                          ),
                        ),
                        OutlinedButton(
                          onPressed: () {
                            _selectStartDate(context);
                          },
                          style: OutlinedButton.styleFrom(
                            side: BorderSide(width: 1.0, color: Colors.grey),
                          ),
                          child: Text(
                            getStartDateText(),
                            style: TextStyle(color: Colors.grey),
                          ),
                        ),
                      ],
                    ),
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: [
                        const Text(
                          'End Date',
                          style: TextStyle(
                            fontSize: 18,
                            color: Colors.black,
                            fontWeight: FontWeight.w500,
                            fontFamily: "Roboto",
                          ),
                        ),
                        OutlinedButton(
                          onPressed: () {
                            _selectEndDate(context);
                          },
                          style: OutlinedButton.styleFrom(
                            side: BorderSide(width: 1.0, color: Colors.grey),
                          ),
                          child: Text(
                            getEndDateText(),
                            style: TextStyle(color: Colors.grey),
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
                const SizedBox(
                  height: 10,
                ),
                const Text(
                  'Project Code',
                  style: TextStyle(
                    fontSize: 18,
                    color: Colors.black,
                    fontWeight: FontWeight.w500,
                    fontFamily: "Roboto",
                  ),
                ),
                Wrap(
                  children: projectCodePosition.toList(),
                ),
                Row(
                  children: [
                    SizedBox.fromSize(),
                    Spacer(),
                    Container(
                      height: 50,
                      width: 150,
                      padding: EdgeInsets.only(right: 15),
                      child: ElevatedButton(
                        style: ButtonStyle(
                            backgroundColor: MaterialStateProperty.all(
                                activateButton == true
                                    ? Color(0xFF023E8A)
                                    : Colors.grey),
                            shape: MaterialStateProperty.all<
                                RoundedRectangleBorder>(RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(10.0),
                            ))),
                        onPressed: () async {
                          if (activateButton == true) {
                            //do whatever you want
                          } else {
                            //don't do anything
                          }
                        },
                        child: Text('Select',
                            style: TextStyle(
                              color: Colors.white,
                              fontWeight: FontWeight.w700,
                              fontFamily: "Roboto",
                              fontSize: 16.0,
                            )),
                      ),
                    ),
                  ],
                ),
                const Text(
                  'Labor',
                  style: TextStyle(
                    fontSize: 18,
                    color: Colors.black,
                    fontWeight: FontWeight.w500,
                    fontFamily: "Roboto",
                  ),
                ),
                Wrap(
                  children: laborPosition.toList(),
                ),
              ],
            )),
      ),
      bottomNavigationBar: Card(
        child: Container(
          padding: EdgeInsets.all(12.0),
          height: 86,
          decoration: const BoxDecoration(
            color: Colors.white,
            boxShadow: <BoxShadow>[
              BoxShadow(
                color: Colors.black54,
                blurRadius: 20.0,
                spreadRadius: -20.0,
                offset: Offset(0.0, -15.0),
              )
            ],
          ),
          child: ElevatedButton(
            style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(Color(0xFF023E8A)),
                shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                    RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(10.0),
                ))),
            onPressed: () async {},
            child: Text('Search',
                style: TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.w700,
                  fontFamily: "Roboto",
                  fontSize: 16.0,
                )),
          ),
        ),
      ),
    );
  }

  Future _selectStartDate(BuildContext context) async {
    final newDate = await showDatePicker(
      context: context,
      initialDate: selectedStartDate,
      firstDate: DateTime(2010),
      lastDate: DateTime(2025),
    );
    if (newDate == null) return;
    setState(() => startDate = newDate);
  }

  _selectEndDate(BuildContext context) async {
    final newDate = await showDatePicker(
      context: context,
      initialDate: selectedEndDate,
      firstDate: DateTime(2010),
      lastDate: DateTime(2025),
    );
    if (newDate == null) return;
    setState(() => endDate = newDate);
  }

  Iterable<Widget> get statusPosition sync* {
    for (FilterWidget company in _status) {
      yield Padding(
        padding: const EdgeInsets.all(6.0),
        child: FilterChip(
          backgroundColor: Colors.white,
          shape: StadiumBorder(
            side: BorderSide(color: Colors.grey, width: 0.5),
          ),
          avatar: CircleAvatar(
            backgroundColor: Colors.cyan,
            child: Text(
              company.name[0].toUpperCase(),
              style: TextStyle(color: Colors.white),
            ),
          ),
          label: Text(
            company.name,
            style: TextStyle(
              color: _isSelected == false ? Colors.grey : Colors.white,
              fontFamily: "Roboto",
            ),
          ),
          selected: _statusFilters.contains(company.name),
          checkmarkColor: Colors.white,
          selectedColor: Color(0xFF023E8A),
          onSelected: (bool selected) {
            setState(() {
              if (selected) {
                _statusFilters.add(company.name);
              } else {
                _statusFilters.removeWhere((String name) {
                  return name == company.name;
                });
              }

              print(_statusFilters.toString());
            });
          },
        ),
      );
    }
  }

  Iterable<Widget> get projectCodePosition sync* {
    for (FilterWidget company in _projectCode) {
      yield Padding(
        padding: const EdgeInsets.all(6.0),
        child: FilterChip(
          backgroundColor: Colors.white,
          shape: StadiumBorder(
            side: BorderSide(color: Colors.grey, width: 0.5),
          ),
          label: Text(
            company.name,
            style: TextStyle(
              color: _isSelected == false ? Colors.grey : Colors.white,
              fontFamily: "Roboto",
            ),
          ),
          selected: _projectCodeFilters.contains(company.name),
          checkmarkColor: Colors.white,
          selectedColor: Color(0xFF023E8A),
          onSelected: (bool selected) {
            setState(() {
              if (selected) {
                _projectCodeFilters.add(company.name);
                 activateButton = true;
              } else {
                _projectCodeFilters.removeWhere((String name) {
  print("hi length is ${_projectCodeFilters.length}");
                  if (_projectCodeFilters.length == 1) activateButton = false;
                  return name == company.name;
                });
              }

              print(_projectCodeFilters.toString());
            });
          },
        ),
      );
    }
  }

  Iterable<Widget> get laborPosition sync* {
    for (FilterWidget company in _labor) {
      yield Padding(
        padding: const EdgeInsets.all(6.0),
        child: FilterChip(
          backgroundColor: Colors.white60,
          shape: StadiumBorder(
            side: BorderSide(color: Colors.grey, width: 0.5),
          ),
          avatar: CircleAvatar(
            backgroundColor: Colors.cyan,
            child: Text(
              company.name[0].toUpperCase(),
              style: TextStyle(color: Colors.white),
            ),
          ),
          label: Text(
            company.name,
            style: TextStyle(
              color: Colors.grey,
              fontFamily: "Roboto",
            ),
          ),
          selected: _laborFilters.contains(company.name),
          selectedColor: Color(0xFF023E8A),
          onSelected: (bool selected) {
            setState(() {
              if (selected) {
                _laborFilters.add(company.name);
              } else {
                _laborFilters.removeWhere((String name) {
                  return name == company.name;
                });
              }

              print(_laborFilters.toString());
            });
          },
        ),
      );
    }
  }
}

class FilterWidget {
  const FilterWidget(this.name);
  final String name;
}

要在 Flutter 中禁用按钮,请将 null 传递给 onPressed 参数。

onPressed: (some_condition is true) ? () {...} : null,