Flutter Listview 在使用 FutureBuilder 加载缩略图时冻结

问题描述 投票:0回答:2

我正在 flutter 中创建一个文件管理器用于学习目的。我刚刚开始学习flutter,所以对此了解不多。

我的问题是我想显示文件夹中图像的缩略图,因为我正在使用 ListView 中的 FutureBuilder 调用用 android 本机代码编写的函数。它工作正常,但每当我打开一个包含大量图像的目录时,它会冻结 UI 一段时间,并且即使异步调用缩略图,我也无法滚动它。

我的Listview代码:-

@override
Widget build(BuildContext context) {
    return new ListView.builder(
      itemBuilder: (itemContext, i) {
        if (_filesList != null && i < _filesList.length) {
          String currDir = _filesList[i]['path'];
          return new ListTile(
            title: new Text(_filesList[i]['name']),
            leading: (_filesList[i]['isDir'] == "false")
                ? new FutureBuilder<Uint8List>(
                    future: _getThumbnail(currDir),
                    builder: (BuildContext context,
                        AsyncSnapshot<Uint8List> snapshot) {
                      switch (snapshot.connectionState) {
                        case ConnectionState.waiting:
                          return new Container(
                            decoration: new BoxDecoration(
                              color: Colors.brown,
                              borderRadius: new BorderRadius.circular(20.0),
                            ),
                            width: 30.0,
                            height: 30.0,
                          );
                        default:
                          if (snapshot.hasError)
                            return new Container(
                              decoration: new BoxDecoration(
                                color: Colors.brown,
                                borderRadius: new BorderRadius.circular(20.0),
                              ),
                              width: 30.0,
                              height: 30.0,
                            );
                          else {
                            return new Image.memory(snapshot.data);
                          }
                      }
                    },
                  )
                : new Container(
                    decoration: new BoxDecoration(
                      color: (_filesList[i]['isDir'] == "true")
                          ? Colors.yellow
                          : Colors.brown,
                      borderRadius: new BorderRadius.circular(20.0),
                    ),
                    width: 30.0,
                    height: 30.0),
            onTap: () {
              setState(() {
                _currentDir = currDir;
              });
              _getFilesList(currDir);
            },
          );
        } else {
          return null;
        }
      },
    );
  }

_getThumbnail() 的代码:-

Future <Uint8List> _getThumbnail(path) async {
    try {
      String thumbnailString =
          await channel.invokeMethod("getThumbnail", {"path": path});
      thumbnailString = thumbnailString.replaceAll('\n', '');
      Uint8List bytes = BASE64.decode(thumbnailString);
      return bytes;
    } on PlatformException catch (e) {
      print("Files Not Found $e{e.message}");
      return null;
    }
  }
android dart flutter
2个回答
0
投票

尽管 Flutter 中的调用是异步的,但 Android 上处理

getThumbnail
的代码可能会阻塞 UI 线程,导致加载冻结或滚动不稳定。解决方案是使用 AsyncTask 构建/获取
doInBackground
中的缩略图并在
onPostExecute
中返回结果。


0
投票

我面对这个问题5个多小时,但终于解决了。首先,遇到此问题的任何人都可以考虑访问此问题: Listview 使 Flutter 应用程序崩溃

上面的链接提供了精彩的答案。

根据我的发现,

ListView.Builder
可能会取无限高度或宽度,具体取决于
scrollDirection
,将其视为无限循环

就我而言,我用容器包裹了

ListView.Builder
,并给出了容器的宽度和高度,我还添加了
shrinkWrap: true
。我是这样解决的:

 return Container(
      width: MediaQuery.of(context).size.width,
      height: 100,
      child: ListView.builder(
          shrinkWrap: true,
          scrollDirection: Axis.horizontal,
          itemCount: files.length,
          itemBuilder: (builderContext, index) {
            return Image.file(File(files[index]!.path));
          }),
    );
  }
© www.soinside.com 2019 - 2024. All rights reserved.