簡體   English   中英

輸入“列表<dynamic> ' 不是類型 'List 的子類型<widget> '</widget></dynamic>

[英]type 'List<dynamic>' is not a subtype of type 'List<Widget>'

我有一段代碼是從 Firestore 示例中復制的:

Widget _buildBody(BuildContext context) {
    return new StreamBuilder(
      stream: _getEventStream(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) return new Text('Loading...');
        return new ListView(
          children: snapshot.data.documents.map((document) {
            return new ListTile(
              title: new Text(document['name']),
              subtitle: new Text("Class"),
            );
          }).toList(),
        );
      },
    );
  }

但我得到這個錯誤

type 'List<dynamic>' is not a subtype of type 'List<Widget>'

這里出了什么問題?

這里的問題是類型推斷以意想不到的方式失敗。 解決方案是為map方法提供一個類型參數。

snapshot.data.documents.map<Widget>((document) {
  return new ListTile(
    title: new Text(document['name']),
    subtitle: new Text("Class"),
  );
}).toList()

更復雜的答案是,雖然children項的類型是List<Widget> ,但該信息不會流回map調用。 這可能是因為map后跟toList並且因為沒有辦法對閉包的返回進行類型注釋。

您可以將動態列表轉換為具有特定類型的列表:

List<'YourModel'>.from(_list.where((i) => i.flag == true));

我通過將Map轉換為Widget解決了我的問題

children: snapshot.map<Widget>((data) => 
    _buildListItem(context, data)).toList(),

我在 Firestore 中有一個字符串列表,我試圖在我的應用程序中讀取這些字符串。 當我嘗試將其轉換為字符串列表時,我遇到了同樣的錯誤。

type 'List<dynamic>' is not a subtype of type 'List<Widget>'

這個解決方案幫助了我。 一探究竟。

var array = document['array']; // array is now List<dynamic>
List<String> strings = List<String>.from(array);

我認為您在某些小部件的屬性中使用了 _buildBody,因此孩子期望一個List Widget (Widget 數組)並且 _buildBody 返回一個'List dynamic'

以一種非常簡單的方式,您可以使用一個變量來返回它:

// you can build your List of Widget's like you need
List<Widget> widgets = [
  Text('Line 1'),
  Text('Line 2'),
  Text('Line 3'),
];

// you can use it like this
Column(
  children: widgets
)

示例( flutter create test1cd test1edit lib/main.dartflutter run ):

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<Widget> widgets = [
    Text('Line 1'),
    Text('Line 2'),
    Text('Line 3'),
  ];

  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("List of Widgets Example")),
        body: Column(
          children: widgets
        )
      )
    );
  }

}

在小部件列表(arrayOfWidgets) 中使用小部件(oneWidget) 的另一個示例。 我展示了一個小部件(MyButton)如何個性化一個小部件並減少代碼的大小:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<Widget> arrayOfWidgets = [
    Text('My Buttons'),
    MyButton('Button 1'),
    MyButton('Button 2'),
    MyButton('Button 3'),
  ];

  Widget oneWidget(List<Widget> _lw) { return Column(children: _lw); }

  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Widget with a List of Widget's Example")),
        body: oneWidget(arrayOfWidgets)
      )
    );
  }

}

class MyButton extends StatelessWidget {
  final String text;

  MyButton(this.text);

  @override
  Widget build(BuildContext context) {
    return FlatButton(
      color: Colors.red,
      child: Text(text),
      onPressed: (){print("Pressed button '$text'.");},
    );
  }
}

我做了一個完整的例子,我使用動態小部件在屏幕上顯示和隱藏小部件,你也可以在dart fiddle上看到它在線運行。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List item = [
    {"title": "Button One", "color": 50},
    {"title": "Button Two", "color": 100},
    {"title": "Button Three", "color": 200},
    {"title": "No show", "color": 0, "hide": '1'},
  ];

  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Dynamic Widget - List<Widget>"),backgroundColor: Colors.blue),
        body: Column(
          children: <Widget>[
            Center(child: buttonBar()),
            Text('Click the buttons to hide it'),
          ]
        )
      )
    );
  }

  Widget buttonBar() {
    return Column(
      children: item.where((e) => e['hide'] != '1').map<Widget>((document) {
        return new FlatButton(
          child: new Text(document['title']),
          color: Color.fromARGB(document['color'], 0, 100, 0),
          onPressed: () {
            setState(() {
              print("click on ${document['title']} lets hide it");
              final tile = item.firstWhere((e) => e['title'] == document['title']);
              tile['hide'] = '1';
            });
          },
        );
      }
    ).toList());
  }
}

也許它可以幫助某人。 如果它對您有用,請讓我知道單擊向上箭頭。 謝謝。

https://dartpad.dev/b37b08cc25e0ccdba680090e9ef4b3c1

這對我List<'YourModel'>.from(_list.where((i) => i.flag == true));

我認為,將 List 的類型從動態更改為 String 並進行熱重載后會出現此錯誤,熱重啟是解決方案..

請記住:熱重啟只重建 build() 函數,而不是整個類&在類頂部聲明 List 不在 build() 函數之外

通過添加.toList()更改為列表解決了問題

例子:

List<dynamic> listOne = ['111','222']
List<String> ListTwo = listOne.cast<String>();

要將每個項目轉換為小部件,請使用ListView.builder()構造函數。

通常,提供一個構建器函數來檢查您正在處理的項目類型,並為該類型的項目返回適當的 Widget。

ListView.builder(
  // Let the ListView know how many items it needs to build.
  itemCount: items.length,
  // Provide a builder function. This is where the magic happens.
  // Convert each item into a widget based on the type of item it is.
  itemBuilder: (context, index) {
    final item = items[index];

    return ListTile(
      title: item.buildTitle(context),
      subtitle: item.buildSubtitle(context),
    );
  },
);

有一條關於用“List myList = [1,2,3]”而不是“List myList = [1,2,3]”聲明您的列表的評論

聲明到“列表”<“小部件”>“myList [1,2,3]”

可以確認這解決了“List”類型的錯誤不是“List”類型的子類型

我的解決方案是,您可以將List<dynamic>轉換為List<Widget> ,您可以在snapshot.data.documents.map之后添加一個簡單代碼到snapshot.data.documents.map<Widget> ,就像我將向您展示的代碼一樣以下

由此

return new ListView(
          children: snapshot.data.documents.map((document) {
            return new ListTile(
              title: new Text(document['name']),
              subtitle: new Text("Class"),
            );
          }).toList(),
        );

進入這個

return new ListView(
          children: snapshot.data.documents.map<Widget>((document) {
            return new ListTile(
              title: new Text(document['name']),
              subtitle: new Text("Class"),
            );
          }).toList(),
        );

改變

List list = [];

對此:

List<Widget> list = [];

解決了我的問題!!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM