失败的断言:第 168 行 pos 15:'icon != null':不是真的

时间:2021-02-09 09:05:00

标签: flutter dart searchbar

我正在 Flutter 中创建一个搜索栏,在执行此操作时我发现了上述错误。它显示 icon != null。我不明白为什么它会显示!谁能告诉我如何解决这个问题。它显示以下错误:

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown building Consumer<PatientDataNotifier>(dirty, dependencies: [_InheritedProviderScope<PatientDataNotifier>]):
'package:flutter/src/material/icon_button.dart': Failed assertion: line 168 pos 15: 'icon != null': is not true.
The relevant error-causing widget was: 
  Consumer<PatientDataNotifier> file:///F:/ShortedCubeSolutionProjects/flutter_data_table/lib/homescreen.dart:124:16
When the exception was thrown, this was the stack: 
#2      new IconButton (package:flutter/src/material/icon_button.dart:168:15)
#3      HomeScreen.build.<anonymous closure> (package:flutter_data_table/homescreen.dart:130:21)
#4      Consumer.buildWithChild (package:provider/src/consumer.dart:177:19)
#5      SingleChildStatelessWidget.build (package:nested/nested.dart:260:41)
#6      StatelessElement.build (package:flutter/src/widgets/framework.dart:4701:28)

下面是我的代码。

class HomeScreen extends StatelessWidget {
  String appBarTitle = 'Patient Details';
  TextEditingController nameController = TextEditingController();

  var icon;
  
  Widget bodyData(PatientDataNotifier patientDataNotifier, BuildContext context) {
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: Container(
        margin: EdgeInsets.only(top: 20.0, left: 10.0, right: 10.0),
        decoration: BoxDecoration(
          border: Border.all(width: 1.0, color: Colors.black),
        ),
        child: DataTable(
        //..........
      );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: PreferredSize(
        preferredSize: const Size.fromHeight(80),
        child: Consumer<PatientDataNotifier>(
          builder: (context,  patientDataNotifier, _){
            return AppBar(
              centerTitle: true,
              title: Text(appBarTitle),
              actions: [
                new IconButton(
                    icon: icon,
                    onPressed: (){
                      if(this.icon == Icons.search){
                        this.icon = new Icon(
                          Icons.close,
                          color: Colors.white,
                        );
                        this.appBarTitle = new TextFormField(
                          controller: nameController,
                          style: new TextStyle(
                              color: Colors.white
                          ),
                          decoration: new InputDecoration(
                            prefixIcon: Icon(Icons.search, color:  Colors.white),
                            hintText: 'Search..',
                            hintStyle: TextStyle(color:  Colors.white),
                          ),
                          onChanged: (text){
                            patientDataNotifier.getPatients(text);
                          },
                        ) as String;
                      }
                    }
                )
              ],
            );
          },

        ),
      ),
      body: Container(
        child: Consumer<PatientDataNotifier>(
          builder: (context, patientDataNotifier, _){
            return bodyData(patientDataNotifier, context);
          },
        ),
      ),
    );
  }
}

请帮我做这件事!我卡住了!

3 个答案:

答案 0 :(得分:0)

您创建了一个名为 varicon,但您没有为其分配值。

尝试向 iconIconButton 参数添加一个有效值。

IconButton(
icon: Icon(Icons.search)
...
),

答案 1 :(得分:0)

您遇到的问题是您的图标为空,并且您无法将空值传递给 iconButton 中的子项。您正在使用无状态小部件,但您应该使用有状态的小部件,因为您希望在更改值时重新加载视图。我对逻辑进行了一些更改,因此当您使用搜索栏时,它会在您的应用中显示一个小部件或另一个小部件。

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {

  TextEditingController nameController = TextEditingController();

  bool textField;

  @override
  void initState() {
    super.initState();
    this.textField = false;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: PreferredSize(
        preferredSize: const Size.fromHeight(80),
        child: AppBar(
          centerTitle: true,
          title: textField ? new TextFormField(
            controller: nameController,
            style: new TextStyle(
                color: Colors.white
            ),
            decoration: new InputDecoration(
              prefixIcon: Icon(Icons.search, color:  Colors.white),
              hintText: 'Search..',
              hintStyle: TextStyle(color:  Colors.white),
            ),
            onChanged: (text){
            },
          ) : Text('Patient Details'),
          actions: [
            new IconButton(
                icon: textField ? new Icon(
                  Icons.close,
                  color: Colors.white,
                ) : Icon(Icons.search),
                onPressed: (){
                  setState(() {
                    this.textField = !this.textField;
                  });
                }
            )
          ],
        ),
      ),
    );
  }
}

如果您要创建搜索栏,我建议您使用搜索委托。

答案 2 :(得分:0)

首先,你永远不会给你的图标一个价值。首先给你的图标一个初始值:

var icon = Icon(Icons.camera, color: Colors.white);

其次,在 onPressed 函数中,您为变量图标分配了一个新值,但 UI 永远不会显示此更改,因为您没有调用 setState。您还要检查您的图标(例如 new Icon(...) 对象)是否等于图标(例如 Icons.camera),后者将始终返回 false,因此它们不是同一类型的对象。

因此更改 onPressed 函数的这一部分:

if (this.icon == Icons.search) {
  this.icon = new Icon(
    Icons.close,
    color: Colors.white,
  );
}

为此:

if (icon.icon == Icons.search) {
  setState(() {
    icon = new Icon(
      Icons.close,
      color: Colors.white,
    );
  });
}