如何使用未来的列表并在 listView 中使用它

How to get use a list from future and use it inside a listView

我正在尝试获取特定目录中所有文件的列表。

我从一个名为 getUserVideos() 的未来函数中获取文件,如果我在函数内部尝试打印数据,我可以看到结果,但我不能在函数外部使用数据。

class _mediaUtentiState extends State<mediaUtenti> {
  var lightBlue = Color.fromRGBO(0, 197, 205, 1.0);
  var _imagesDir;


  @override
  void initState() {
    super.initState();
    getUsersVideos();
  }

  List<String> Names = [
    'Abhishek',
    'John',
    'Robert',
    'Shyam',
    'Sita',
    'Gita',
    'Nitish'
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: lightBlue,
      appBar: new AppBar(
        title: Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            Container(padding: const EdgeInsets.all(8.0), child: Text('Nome')),
            Container(
              child: CircleAvatar(
                backgroundImage: NetworkImage('http://i.pravatar.cc/300'),
              ),
            ),
          ],
        ),
        backgroundColor: purple,
      ),

      body: new Container(
        child: new ListView.builder(
          reverse: false,
          itemBuilder: (_, int index) => EachList(this.Names[index]),
          itemCount: this.Names.length,
        ),
      ),
    );
  }

  Future<String> getUsersVideos() async {
    print('something');
    final Directory extDir = await getExternalStorageDirectory();
    final String dirPath = '${extDir.path}/Movies/Veople';
    final myDir = new Directory(dirPath);
    List<FileSystemEntity> _images;
    _images = myDir.listSync(recursive: true, followLinks: false);
    print(_images.length);
    _imagesDir = _images;
  }
}

class EachList extends StatelessWidget {
  final String name;
  EachList(this.name);
  @override
  Widget build(BuildContext context) {
    return new Card(
      child: new Container(
        padding: EdgeInsets.all(8.0),
        child: new Row(
          children: <Widget>[
            new CircleAvatar(
              child: new Text(name[0]),
            ),
            new Padding(padding: EdgeInsets.only(right: 10.0)),
            new Text(
              name,
              style: TextStyle(fontSize: 20.0),
            )
          ],
        ),
      ),
    );
  }
}

现在我只显示名称列表,但我想为路径中的每个文件显示一张卡片。

例如,在函数 getUserVideos() 中,当我尝试打印 imagesDir 时,我得到了正确的结果 [File: '/storage/emulated/0/Movies/Veople/1556217605345.mp4', File: '/storage/emulated/0/Movies/Veople/1556217605345.png', File: '/storage/emulated/0/Movies/Veople/1556217632709.mp4', File: ...] 但是我无法以任何方式从该函数访问 _imageDir。

我确定可以用几行代码解决这个问题,但现在已经 3 个小时了,我无法得到解决方案。

谢谢!

我认为这肯定已经得到了回答,但是虽然有很多关于 FutureBuilder 和列表的问题,none 很像这样或者还没有得到充分的回答。

我会这样做:

import 'dart:io';

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

Future<List<FileSystemEntity>> _getUsersVideos() async {
  print('something');
  final Directory extDir = await getExternalStorageDirectory();
  final String dirPath = '${extDir.path}/Movies/Veople';
  final myDir = new Directory(dirPath);
  List<FileSystemEntity> _images = myDir.listSync(recursive: true, followLinks: false);
  return _images;
}

class ListFromFuture extends StatefulWidget {
  @override
  _ListFromFutureState createState() => _ListFromFutureState();
}

class _ListFromFutureState extends State<ListFromFuture> {
  Future<List<FileSystemEntity>> future;

  @override
  void initState() {
    super.initState();
    future = _getUsersVideos();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: future,
      builder: (context, snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.none:
          case ConnectionState.waiting:
          case ConnectionState.active:
            return Container(
              alignment: Alignment.center,
              child: Text("Loading"),
            );
            break;
          case ConnectionState.done:
            if (snapshot.hasError) {
              // return whatever you'd do for this case, probably an error
              return Container(
                alignment: Alignment.center,
                child: Text("Error: ${snapshot.error}"),
              );
            }
            var data = snapshot.data;
            return new ListView.builder(
              reverse: false,
              itemBuilder: (_, int index) => EachList(data[index]),
              itemCount: data.length,
            );
            break;
        }
      },
    );
  }
}

其中的重要部分是:

  1. future只是设置了initState,没有build函数。这确保每次构建小部件时都不会调用它
  2. 我处理所有出现错误或未来尚未完成的情况。

老实说,您的示例实际上非常接近于正常运行。您所要做的就是将设置 _imagesDir = images 的行换行到 setState(() => ...) 中,它应该可以工作(假设列表不 return 为空)。不过,您还应该检查 _imagesDir == null,否则您可能会遇到空指针异常。