【问题标题】:type 'Future<dynamic>' is not a subtype of type 'List<Application>?''Future<dynamic>' 类型不是 'List<Application>?' 类型的子类型
【发布时间】:2021-05-14 05:41:11
【问题描述】:

我正在尝试在颤振中创建一个搜索小部件,对于列表,我使用了 device_apps (https://pub.dev/packages/device_apps) 的应用程序列表。但我得到一个错误“类型'未来'不是类型'列表的子类型?'”。为了创建搜索小部件,我使用了来自 this link 的帮助。

这是我的代码:

import 'dart:async';

import 'package:device_apps/device_apps.dart';
import 'package:flutter/material.dart';


class SearchWidget extends StatelessWidget {
  SearchWidget({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        children: <Widget>[
          TextField(onChanged: _filter),
          StreamBuilder<List<Application>>(
            initialData: lelist(),
            stream: _stream,
            builder:
                    (BuildContext context, AsyncSnapshot<List<Application>> snapshot) {
                  print(snapshot.data);
                  return ListView.builder(
                    shrinkWrap: true,
                    itemCount: snapshot.data.length,
                    itemBuilder: (BuildContext context, int index) {
                      return Text(snapshot.data[index].appName);
                    },
                  );
                },
              )


        ],
      ),
    );
  }
}

StreamController<List<Application>> _streamController = StreamController<List<Application>>();
Stream<List<Application>> get _stream => _streamController.stream;
_filter(String searchQuery) {
  List<Application> _filteredList = lelist()
      .where((Application app) => app.appName.toLowerCase().contains(searchQuery.toLowerCase()))
      .toList();
  _streamController.sink.add(_filteredList);
}

lelist() async {
  List<Application> _dataFromQuerySnapShot = await DeviceApps.getInstalledApplications(includeAppIcons: true);
  _dataFromQuerySnapShot.sort((a, b) {
    return a.appName.toString().toLowerCase().compareTo(b.appName.toString().toLowerCase());
  });
  return _dataFromQuerySnapShot;
}



【问题讨论】:

    标签: android flutter flutter-dependencies


    【解决方案1】:

    我认为没有必要在每次击键时加载和排序已安装的应用程序,因此将所有这些逻辑放入 initState。这也使您的 _filter 函数同步。

    import 'dart:async';
    
    import 'package:device_apps/device_apps.dart';
    import 'package:flutter/material.dart';
    
    class SearchWidget extends StatefulWidget {
      SearchWidget({Key key}) : super(key: key);
    
      @override
      _SearchWidgetState createState() => _SearchWidgetState();
    }
    
    class _SearchWidgetState extends State<SearchWidget> {
      final _streamController = StreamController<List<Application>>();
      List<Application> _dataFromQuerySnapShot;
    
      Stream<List<Application>> get _stream => _streamController.stream;
    
      @override
      void initState() {
        DeviceApps.getInstalledApplications(includeAppIcons: true)
            .then((List<Application> apps) {
          _dataFromQuerySnapShot = apps;
          _dataFromQuerySnapShot.sort((a, b) {
            return a.appName
                .toString()
                .toLowerCase()
                .compareTo(b.appName.toString().toLowerCase());
          });
          _streamController.sink.add(_dataFromQuerySnapShot);
        });
        super.initState();
      }
    
      @override
      void dispose() {
        _streamController.close();
        super.dispose();
      }
    
      _filter(String searchQuery) {
        final filteredApplications = _dataFromQuerySnapShot
            .where((Application app) =>
                app.appName.toLowerCase().contains(searchQuery.toLowerCase()))
            .toList();
        _streamController.sink.add(filteredApplications);
      }
    
      @override
      Widget build(BuildContext context) {
        return SingleChildScrollView(
          child: Column(
            children: <Widget>[
              TextField(onChanged: _filter),
              StreamBuilder<List<Application>>(
                stream: _stream,
                builder: (BuildContext context,
                    AsyncSnapshot<List<Application>> snapshot) {
                  if (!snapshot.hasData) {
                    return Center(child: CircularProgressIndicator());
                  }
                  return snapshot.data.isEmpty
                      ? Center(child: Text('Empty'))
                      : ListView.builder(
                          shrinkWrap: true,
                          itemCount: snapshot.data.length,
                          itemBuilder: (BuildContext context, int index) {
                            return Text(snapshot.data[index].appName);
                          },
                        );
                },
              )
            ],
          ),
        );
      }
    }
    

    【讨论】:

    • 我试过了,但得到了错误:“参数类型'Future>'不能分配给参数类型'List'”
    • 您不能使用 lelist() 作为您的 initialData 的值,因为它返回的是 Future。为 initialData 提供不同的值或将其删除,然后在等待流中的第一个值时使用 if (!snapshot.hasData) { return CircularProgressIndicator() } 之类的值。
    • 我删除了 initialData 并使用了 CircularProgressIndicator()...但现在在 print(snapshot.data) 中我得到 I/flutter (26265): null 并且圆形指示器正在旋转而不显示任何列表。 .....当我在 TextField 中输入单词时,我在控制台中遇到另一个错误:未处理的异常:类型'Future' 不是类型'List' 的子类型
    • 我尝试使用 initialData: lelist() as List,但它显示相同的错误:'Future' is not a subtype of type 'List' in type演员
    【解决方案2】:

    我认为你需要在调用你的未来之后添加 asList。

    lelist() async {
     List<Application> _dataFromQuerySnapShot = await 
       DeviceApps.getInstalledApplications(includeAppIcons: true);
        _dataFromQuerySnapShot.sort((a, b) {
        return 
        a.appName.toString().toLowerCase().compareTo(b.appName.toString().toLowerCase());
     }) as List;
     return _dataFromQuerySnapShot;
    

    }

    【讨论】:

    • 不,使用 as List 后仍然报同样的错误。
    猜你喜欢
    • 2020-09-20
    • 1970-01-01
    • 2021-08-13
    • 2020-09-08
    • 2020-02-28
    • 2021-10-20
    • 2019-12-31
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多