【问题标题】:type 'Null' is not a subtype of type 'Icon'“Null”类型不是“Icon”类型的子类型
【发布时间】:2021-08-04 17:52:51
【问题描述】:

尝试将图标添加到我的列表磁贴后,我经常收到此错误:

════════ Exception caught by widgets library ═══════════════════════════════════
The following _TypeError was thrown building Alertbox(dirty, state: _AlertboxState#08465):
type 'Null' is not a subtype of type 'Icon'

The relevant error-causing widget was
Alertbox
lib/screens/team_screen.dart:58
When the exception was thrown, this was the stack
#0      _AlertboxState.build
package:trainings_app/widgets/alertbox_widget.dart:76
#1      StatefulElement.build
package:flutter/…/widgets/framework.dart:4691
#2      ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4574
#3      StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:4746
#4      Element.rebuild
package:flutter/…/widgets/framework.dart:4267
...
════════════════════════════════════════════════════════════════════════════════

以下是错误引用的类: team_screen

  void newTeam() {
    showDialog<Alertbox>(
      context: context,
      builder: (BuildContext context) {
        return Alertbox('Namen auswählen:', addTeam);
      },
    );
  }

alertbox_widget:错误是由 TextField 中的“onSubmitted”引起的

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:trainings_app/config/palette.dart';

class Alertbox extends StatefulWidget {
  final String title;
  final Function(String, Icon) parseText;
  const Alertbox(this.title, this.parseText);

  @override
  _AlertboxState createState() => _AlertboxState(title, parseText);
}

class _AlertboxState extends State<Alertbox> {
  final String title;
  final Function(String, Icon) parseText;
  final textController = TextEditingController();

  _AlertboxState(this.title, this.parseText);

  var iconChoice;
  List icons = [
    Icons.sports_volleyball_outlined,
    Icons.sports_handball_outlined,
    Icons.sports_baseball_outlined,
  ];

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

  @override
  Widget build(BuildContext context) {
    return Dialog(
      backgroundColor: Colors.transparent,
      elevation: 0,
      insetPadding: EdgeInsets.all(10),
      child: Center(
        child: Container(
          decoration: new BoxDecoration(
            borderRadius: new BorderRadius.all(const Radius.circular(20)),
            color: Colors.white,
          ),
          padding: const EdgeInsets.all(16.0),
          child: SizedBox(
            height: 100,
            child: Column(
              children: [
                Text(
                  title,
                  style: TextStyle(
                    fontSize: 18,
                  ),
                ),
                Row(
                  children: [
                    DropdownButton(
                      value: iconChoice,
                      onChanged: (newIcon) {
                        setState(() {
                          iconChoice = newIcon;
                        });
                      },
                      items: icons.map((icon) {
                        return DropdownMenuItem(
                          value: icon,
                          child: Icon(icon),
                        );
                      }).toList(),
                    ),
                    SizedBox(width: 12),
                    Expanded(
                      child: TextField(
                        onSubmitted: parseText(textController.text, iconChoice),
                        autofocus: true,
                        textAlign: TextAlign.center,
                        controller: textController,
                      ),
                    ),
                    SizedBox(width: 12),
                    ElevatedButton(
                      onPressed: () {
                        parseText(textController.text, iconChoice);
                      },
                      child: const Icon(CupertinoIcons.checkmark),
                      style: ButtonStyle(
                        backgroundColor:
                            MaterialStateProperty.all(Palette.orange),
                      ),
                    ),
                    SizedBox(width: 8),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

我希望任何人都可以帮助我或有某种解决方案/解决方法来帮助解决这个问题

【问题讨论】:

    标签: flutter icons


    【解决方案1】:

    所以我花了一段时间才弄清楚问题出在哪里,但我想我明白了。

    我不确切知道您计划的功能 - 例如当字段为空(文本和/或图标)时,您是否进行任何验证?您可能应该通过停用按钮或显示错误消息来捕捉到这一点。但除此之外:

    // method which is called when clicking the submit button
    addTeam(String text, Icon icon) {
      // do whatever you do in here
      log('$text $icon');
    }
    
    class Alertbox extends StatefulWidget {
      // you dont need to pass the title to the state, you can access it via 
      // widget.title, same for the onParseText method
      final String title;
      final Function(String, Icon) onParseText;
    
      const Alertbox(this.title, this.onParseText);
    
      @override
      _AlertboxState createState() => _AlertboxState();
    }
    
    class _AlertboxState extends State<Alertbox> {
      final textController = TextEditingController();
    
      // you somehow messed up Icon and IconData, try to define which type it is
      // it can be null since there is no default icon set
      Icon? iconChoice;
    
      // also define the type for the list
      List<Icon> icons = [
        Icon(Icons.sports_volleyball_outlined),
        Icon(Icons.sports_handball_outlined),
        Icon(Icons.sports_baseball_outlined),
      ];
    
      @override
      void dispose() {
        textController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Dialog(
          backgroundColor: Colors.transparent,
          elevation: 0,
          insetPadding: EdgeInsets.all(10),
          child: Center(
            child: Container(
              decoration: new BoxDecoration(
                borderRadius: new BorderRadius.all(const Radius.circular(20)),
                color: Colors.white,
              ),
              padding: const EdgeInsets.all(16.0),
              child: SizedBox(
                height: 100,
                child: Column(
                  children: [
                    Text(
                      widget.title,
                      style: TextStyle(
                        fontSize: 18,
                      ),
                    ),
                    Row(
                      children: [
                        // you can define the value type of the Dropdown, set it 
                        // to Icon
                        DropdownButton<Icon>(
                          value: iconChoice,
                          onChanged: (newIcon) {
                            setState(() {
                              iconChoice = newIcon;
                            });
                          },
                          items: icons.map((icon) {
                            return DropdownMenuItem(
                              value: icon,
                              child: icon,
                            );
                          }).toList(),
                        ),
                        SizedBox(width: 12),
                        Expanded(
                          child: TextField(
                            onSubmitted: (text) {
                              // this is what causes the error.
                              // you have to check if iconChoice is null
                              // I'm not really sure why you use onSubmitted 
                              // here since you already have the submitbutton?
                              if (iconChoice != null) {
                                widget.onParseText(text, iconChoice!);
                              }
                            },
                            autofocus: true,
                            textAlign: TextAlign.center,
                            controller: textController,
                          ),
                        ),
                        SizedBox(width: 12),
                        ElevatedButton(
                          onPressed: () {
                            // you need to make sure iconChoice is not null
                            // before calling that method. Use some kind of 
                            // validation here, like mentioned above
                            widget.onParseText(textController.text, 
                            iconChoice!);
                          },
                          child: const Icon(CupertinoIcons.checkmark),
                          style: ButtonStyle(
                            backgroundColor:
                                MaterialStateProperty.all(Colors.orange),
                          ),
                        ),
                        SizedBox(width: 8),
                      ],
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 我现在初始化了它,但这会导致以下错误imgur
    • 好的,是的。这是因为 Dropdown 需要一个不为空的值。我将使用该解决方案创建一个 Dartpad,使其更容易。
    • @Obscuritas 我更新了我的答案。现在应该可以工作了,请检查。
    猜你喜欢
    • 2021-10-16
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-18
    • 2023-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多