टाइप करें 'लिस्ट <डायनेमिक>' टाइप 'लिस्ट <विजेट>' का उपप्रकार नहीं है


85

मेरे पास कोड का एक स्निपेट है जिसे मैंने 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>'

यहाँ क्या गलत है?

जवाबों:


185

यहाँ समस्या यह है कि अप्रत्याशित प्रकार से निष्कासन विफल हो जाता है। समाधान 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और क्योंकि क्लोजर की वापसी को एनोटेट टाइप करने का कोई तरीका नहीं है।


1
Dart 2 का उपयोग करके मजबूत-मोड या स्पंदन से संबंधित हो सकता है
Rémi Rousselet

यह विशिष्ट परिवर्तन संभवतः गतिशील रूप से नीचे उर्फ ​​"फजी तीर" के रूप में संबंधित है - पहले यह एक सूची <डायनेमिक> को एक सूची <X> असाइन करने के लिए ठीक था। यह बहुत सारे अनुमान अंतराल को कवर करता है।
जोना विलियम्स

1
TBH मैं उसके बग को पुन: पेश करने में कामयाब नहीं हुआ। चूँकि उसके कोड को List<ListTile>बिना निर्दिष्ट किए भी उसका अनुमान लगाया जाता है map
रेमी रूसेलेट

2
खैर उस मुद्दे को हल किया। लेकिन यह थोड़ा अजीब है, मैं डार्ट करने के लिए नया हूं, इसलिए मैं वास्तव में यह नहीं बता सकता कि मैंने इसे समझा।
अराश

मैं एक ही मुद्दे का सामना कर रहा था (लेकिन मेरा परिदृश्य अलग था)। मुझे लगता है कि डार्ट 2 मजबूत प्रकार के कारण ऐसा हो रहा है। एक बार जब मैंने चर घोषणा को सूची <विजेट> में बदल दिया तो यह काम करने लगा।
मनीष कुमार

13

आप विशिष्ट प्रकार के साथ सूची के लिए गतिशील सूची कास्ट कर सकते हैं:

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


3

मुझे लगता है कि आप कुछ विजेट के बच्चों के गुणों में _buildBody का उपयोग करते हैं , इसलिए बच्चों को एक सूची विजेट ( विजेट की सरणी) और _buildBody एक 'सूची गतिशील' देता है

बहुत ही सरल तरीके से, आप इसे वापस करने के लिए एक चर का उपयोग कर सकते हैं:

// 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
)

उदाहरण ( स्पंदन बनाएँ test1 ; cd test1 ; संपादित करें lib / main.dart ; फ़्लटर रन )

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) के भीतर । मैं दिखाता हूं कि विजेट को निजीकृत करने और कोड के आकार को कम करने के लिए एक विजेट (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'.");},
    );
  }
}

मैंने एक पूर्ण उदाहरण बनाया कि मैं स्क्रीन पर विजेट्स को दिखाने और छिपाने के लिए डायनामिक विजेट का उपयोग करता हूं , आप इसे डार्ट फ़िडल पर भी ऑनलाइन देख सकते हैं ।

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


यह अब काम नहीं कर रहा है। सरणी Text('My Buttons')में उदा असाइन नहीं कर सकता List<Widget>। हो रही है The element type 'Text' can't be assigned to the list type 'Widget'। इसके लिए वर्कअराउंड क्या होगा?
शिमो

पाठ एक विजेट है और सूची <विजेट> का एक तत्व हो सकता है। इस पैड की जांच करें https://dartpad.dev/6a908fe99f604474fd052731d59d059c और मुझे बताएं कि क्या यह आपके लिए काम करता है।
lynx_74


0

प्रत्येक आइटम को एक विजेट में बदलने के लिए, सूची दृश्य (बिल्डर) का उपयोग करें।

सामान्य तौर पर, एक बिल्डर फ़ंक्शन प्रदान करता है जो इस बात की जांच करता है कि आप किस प्रकार के आइटम के साथ काम कर रहे हैं, और उस प्रकार के आइटम के लिए उपयुक्त विजेट लौटाते हैं।

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),
    );
  },
);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.