首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >未处理的异常:键入'_DropdownRouteResult<int>‘不是'int?’类型的子类型。从Navigator.pop()返回值时

未处理的异常:键入'_DropdownRouteResult<int>‘不是'int?’类型的子类型。从Navigator.pop()返回值时
EN

Stack Overflow用户
提问于 2022-07-22 06:33:54
回答 1查看 60关注 0票数 0

DropdownButtonFormField中,我有一个从提供程序中填充的标准DropdownMenuItems列表和一个"Add“按钮,该按钮按下包含FormMaterialRoute。提交时,表单通过Provider异步将新数据插入到数据库,并在对Navigator.pop()的调用中返回db id。

预期的行为是pop()回调应该将下拉字段的值设置为返回的int值,并关闭下拉菜单,并反映更新后的值。

在下面的代码片段中,我有两个版本的"Add“DropdownMenuItem。“工作”版本按照预期执行,但在按下下拉菜单时不会关闭(也像预期的那样,因为它是一个按钮,而不是一个正常的下拉元素)。

“损坏”版本未能推动新的路线,并抛出

代码语言:javascript
运行
复制
E/flutter (24895): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: type '_DropdownRouteResult<int>' is not a subtype of type 'int?'
E/flutter (24895): #0      _TeaProducerFormFieldState.build.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:teavault/screens/stash/teaform.dart:70:15)
E/flutter (24895): #1      State.setState (package:flutter/src/widgets/framework.dart:1109:30)
E/flutter (24895): #2      _TeaProducerFormFieldState.build.<anonymous closure>.<anonymous closure> (package:teavault/screens/stash/teaform.dart:69:13)
E/flutter (24895): #3      _rootRunUnary (dart:async/zone.dart:1434:47)
E/flutter (24895): #4      _CustomZone.runUnary (dart:async/zone.dart:1335:19)

这里提到的L70是_selectedValue = value;。无论我使用异步/等待还是.then()语法,都会发生这种行为。

我不知道这是因为一次先发制人的检查,还是因为我错过了一些东西而无法等待承诺。

有关守则如下:

代码语言:javascript
运行
复制
class _TeaProducerFormFieldState extends State<TeaProducerFormField> {
  int? _selectedValue;

  @override
  Widget build(BuildContext context) {

    final teaProducers = Provider.of<TeaProducerCollectionModel>(context).items;
    final teaProducerListItems = teaProducers.map((producer) => DropdownMenuItem<int>(
      value: producer.id,
      child: Text(producer.name),
    )).toList();

    final workingAddNewTeaProducerButton = DropdownMenuItem<int>(child: TextButton(
        onPressed: () async {
          final int newValue = await Navigator.push(context, AddNewTeaProducerRoute());
          setState(() {
            _selectedValue = newValue;
          });
        },
        child: Text('Add New Manufacturer')));

    final brokenAddNewTeaProducerButtion = DropdownMenuItem<int>(
        onTap: () {
          Navigator.push(context, AddNewTeaProducerRoute()).then((value) {
            setState(() {
              _selectedValue = value;
            });
          });
        },
        value: 0,
        child: const Text('Add New Manufacturer'));

    return DropdownButtonFormField(
      value: _selectedValue,
      items: teaProducerListItems + [brokenAddNewTeaProducerButtion],
      // child: addNewTeaProducerButton)],
      onChanged: (_) {},
      hint: Text('Select a manufacturer'),
    );
  }

}

编辑:在修改per @Axel的建议并为清晰起见直接插入子树内容之后,我有以下内容,但仍然收到

代码语言:javascript
运行
复制
When the exception was thrown, this was the stack: 
#0      LocalHistoryRoute.didPop (package:flutter/src/widgets/routes.dart)
#1      _RouteEntry.handlePop (package:flutter/src/widgets/navigator.dart:2896:16)
#2      NavigatorState._flushHistoryUpdates (package:flutter/src/widgets/navigator.dart:3868:22)
#3      NavigatorState.pop (package:flutter/src/widgets/navigator.dart:4910:7)
#4      Navigator.pop (package:flutter/src/widgets/navigator.dart:2432:27)
#5      _DropdownMenuItemButtonState._handleOnTap (package:flutter/src/material/dropdown.dart:148:15)

我想将int?类型的arg添加到相关的MaterialPageRoute中,但是得到了相同的结果。

代码语言:javascript
运行
复制
final brokenAddNewTeaProducerButton = DropdownMenuItem<int>(
        onTap: () {
          Navigator.push<int?>(context, MaterialPageRoute(
              builder: (BuildContext context) =>
                  Scaffold(
                      appBar: AppBar(
                        iconTheme: IconThemeData(color: Colors.white),
                        title: Text('Define new Manufacturer'),
                      ),
                      body: Column(
                        children: <Widget>[
                          Expanded(
                            flex: MediaQuery.of(context).orientation == Orientation.portrait ? 4 : 1,
                            child: Container(),
                          ),
                          Expanded(
                            flex: 16,
                            child: Container(
                              padding: const EdgeInsets.symmetric(horizontal: 50.0),
                              child: const TeaProducerForm(),
                            ),
                          ),
                        ],
                      )
                  ))).then((value) {
            setState(() {
              _selectedValue = value;
            });
          });
        },
        value: 0,
        child: const Text('Add New Manufacturer'));

//[...]

class TeaProducerFormState extends State<TeaProducerForm> {
  final _formKey = GlobalKey<FormState>();

  String? fullName;
  String? shortName;

  @override
  Widget build(BuildContext context) {
    // Build a Form widget using the _formKey created above.
    return Form(
      key: _formKey,
      child: Column(
        children: <Widget>[
          TextFormField(
            onSaved: ((value) {fullName = value;}),
            decoration: const InputDecoration(
              hintText: 'Enter full name',
              labelText: 'Full Name'
            ),
          ),
          TextFormField(
            onSaved: ((value) {shortName = value;}),
            decoration: const InputDecoration(
                hintText: 'Enter abbreviated name',
                labelText: 'Short Name'
            ),
            validator: ((value) {
              if ((value ?? '').length > 6 ) {
                return 'Please enter a name with six or fewer characters';
              } else if ((value ?? '').isEmpty ) {
                return 'Please enter a name with one or more characters';
              }
            }),
          ),
          ElevatedButton(
              onPressed: () async {
                if (_formKey.currentState?.validate() ?? false) {

                  ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Saving new manufacturer...')),);
                  _formKey.currentState?.save();

                  final teaProducers = Provider.of<TeaProducerCollectionModel>(context, listen: false);
                  teaProducers.insert(TeaProducer(
                      name: fullName!,
                      shortName: shortName!
                  )).then((value) {
                    print('added tea as id $value');
                    ScaffoldMessenger.of(context).clearSnackBars();
                    Navigator.pop<int?>(context, value);
                  });
                }
            },
            child: const Text('Submit'))
          // Add TextFormFields and ElevatedButton here.
        ],
      ),
    );
  }
}
EN

回答 1

Stack Overflow用户

发布于 2022-07-22 08:47:08

尝试指定您期望从Navigator.push中返回的类型以及在Navigator.pop中AddNewTeaProducerRoute中希望返回的类型。

您的代码应该如下所示:

代码语言:javascript
运行
复制
final brokenAddNewTeaProducerButtion = DropdownMenuItem<int>(
    onTap: () {
      Navigator.push<int?>(context, AddNewTeaProducerRoute()).then((value) {
        setState(() {
          _selectedValue = value;
        });
      });
    },
    value: 0,
    child: const Text('Add New Manufacturer'));

在AddNewTeaProducerRoute内部,请做:

代码语言:javascript
运行
复制
Navigator.pop<int?>(context, value);

在此之后,您不应该得到任何强制转换异常。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73076016

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档