【问题标题】:Flutter add to List<Widget> crashes beacuase of type issues由于类型问题,Flutter 添加到 List<Widget> 崩溃
【发布时间】:2021-02-15 06:29:55
【问题描述】:

我有一个不明白的问题。

   Widget build(BuildContext context) {
    List<Widget> menuList = menuCategories.map((category) {
      return ExpansionTile(
          title: CustomExpansionTileHeader(
            icon: category.icon,
            label: category.label,
          ),
          children: category.children
              .map((item) => ListTile(
                    title: Text(item.label),
                    onTap: item.onTap,
                  ))
              .toList());
    }).toList();
    print(menuList);
    menuList.insert(
        0,
        DrawerHeader(
            child: Text(
              '',
              style: TextStyle(color: Colors.white, fontSize: 25),
            ),
            decoration: BoxDecoration(
              color: Colors.green,
              // image: DecorationImage(
              // fit: BoxFit.fill,
              // image: AssetImage('assets/images/cover.jpg'))),
            )));
    return Drawer(
      child: ListView(padding: EdgeInsets.zero, children: menuList

如您所见,我正在尝试使用一些 ExpansionTile 小部件创建列表类型小部件,但还将 DrawerHeader 添加为索引 0。之后,我想在子列表中的抽屉小部件中返回列表。

当我打印 menuList(在将 DrawerHeader 添加到列表之前)时,它打印 [ExpansionTile、ExpansionTile、ExpansionTile、ExpansionTile],当我打印 menuList.runtimeType 时,我得到列表类型 ExpansionTile。 这是我不明白的部分。该列表应该是 Widget 列表,但它以某种方式更改了。

当我将 DrawerHeader 添加到列表时,这会导致崩溃,因为它是不同的提示。

如果这很重要,我正在构建 Flutter 网络应用。

请帮忙:)

【问题讨论】:

  • 我是吗?根据插入方法的颤振文档定义:'在此列表中的位置 [index] 处插入对象。这会将列表的长度增加一,并将索引处或之后的所有对象移向列表的末尾。据我了解,这种方法应该只是增加列表的长度。

标签: flutter flutter-web flutter-widget flutter-typeahead


【解决方案1】:

当您执行List&lt;Widget&gt; menuList = menuCategories.map((category) { 时,请使用通用字段指定类型。 Dart 错误地推断您希望此可迭代对象的类型为 ExpansionTile

List<Widget> menuList = menuCategories.map<Widget>((category) {

更明确地告诉 dart 你希望这是什么类型。

【讨论】:

    【解决方案2】:

    @Christopher Moore 的答案比下面提到的方法更好。

    映射后的tooList()调用总是返回List&lt;ExpansionTile&gt;。这更像是一种 Dart 类型的安全机制。因此,与其插入现有列表,不如将其收集为单独的列表并使用扩展运算符并将这些元素添加到新列表中,如下所示。实时版本在 dartpad 中可用 here

    import 'package:flutter/material.dart';
    
    final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            appBar: AppBar(
              title: const Text('Drawer Demo'),
            ),
            drawer: MyWidget(),
            body: Center(
              child: Text('Hello'),
            ),
          ),
        );
      }
    }
    
    class Item {
      String label;
      Function onTap;
      Item({this.label, this.onTap});
    }
    
    class Category {
      Icon icon;
      String label;
      List<Item> children;
      Category({this.icon, this.label, this.children});
    }
    
    class MyWidget extends StatelessWidget {
      final menuCategories = [
        Category(
          icon: Icon(Icons.ac_unit),
          label: 'ac_unit',
          children: [
            Item(label: 'Voltas'),
            Item(label: 'Haier'),
          ],
        ),
        Category(
          icon: Icon(Icons.computer),
          label: 'computers',
          children: [
            Item(label: 'HP'),
            Item(label: 'Dell'),
          ],
        ),
      ];
      @override
      Widget build(BuildContext context) {
        final categoryList = menuCategories.map((Category category) {
          return ExpansionTile(
              title: ListTile(
                title: Text(category.label),
              ),
              children: category.children
                  .map((item) => ListTile(
                        title: Text(item.label),
                        onTap: item.onTap,
                      ))
                  .toList());
        }).toList();
    
        List<Widget> menuList = [
          DrawerHeader(
            child: Text(
              'Categories',
              style: TextStyle(color: Colors.white, fontSize: 25),
            ),
            decoration: BoxDecoration(
              color: Colors.green,
              // image: DecorationImage(
              // fit: BoxFit.fill,
              // image: AssetImage('assets/images/cover.jpg'))),
            ),
          ),
          ...categoryList
        ];
        return Drawer(
            child: ListView(padding: EdgeInsets.zero, children: menuList));
      }
    }
    
    

    您可以在普通 dartpad 中测试以下代码,以验证与您看到的相同的问题。

    void main() {
      List<A> menus = [B('s'),B('fd')].toList();
      menus.insert(0, C('1'));
      print(menus);
    }
    
    class A {
      
    }
    
    class B extends A {
      String label;
      B(this.label);
    }
    
    class C extends A {
      String label;
      C(this.label);
    }
    

    【讨论】:

      猜你喜欢
      • 2020-04-07
      • 2021-11-09
      • 1970-01-01
      • 1970-01-01
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      • 2020-12-10
      • 2021-06-04
      相关资源
      最近更新 更多