【问题标题】:How to read audio extensions in Flutter and display in a ListView?如何在 Flutter 中读取音频扩展并在 ListView 中显示?
【发布时间】:2018-12-06 17:54:10
【问题描述】:

如何在 Flutter 中创建一个从 SD 卡读取音频文件并将其显示到 ListView 的函数?

【问题讨论】:

    标签: android dart flutter


    【解决方案1】:

    如果您询问显示音频文件列表 - 这是我的代码示例:

    import 'dart:async';
    import 'dart:io';
    
    import 'package:flutter/material.dart';
    import 'package:flutter_app/storage.dart';
    import 'package:path_provider/path_provider.dart';
    import 'package:simple_permissions/simple_permissions.dart';
    
    class BrowserScaffold extends StatefulWidget {
      @override
      State<StatefulWidget> createState() {
        return _BrowserScaffoldState();
      }
    }
    
    class _BrowserScaffoldState extends State<BrowserScaffold> {
      final List<FileSystemEntity> files = List<FileSystemEntity>();
      final savedFiles = Set<File>();
      Directory parent;
      ScrollController controller = ScrollController();
    
      @override
      Widget build(BuildContext context) {
        if (parent == null) {
          SimplePermissions
              .requestPermission(Permission.WriteExternalStorage)
              .then((value) {
            if (value == PermissionStatus.authorized) {
              localPath.then((String value) {
                Directory dir = Directory(value);
                while (dir.path != dir.parent.path) {
                  dir.isAbsolute;
                  dir = dir.parent;
                }
                parent = dir;
                setState(() {
                  files.addAll(dir.parent.listSync());
                  sortFiles();
                });
              });
            } else {
              SimplePermissions.openSettings();
            }
          });
        }
        return Scaffold(
          appBar: AppBar(
            title: Text('Files'),
            actions: <Widget>[
              IconButton(icon: Icon(Icons.check), onPressed: apply),
            ],
          ),
          body: buildList(),
        );
      }
    
      void sortFiles() {
        for (int i = files.length - 1; i >= 0; i--) {
          FileSystemEntity entity = files[i];
          if (entity is Link) {
            files.remove(entity);
          } else if (entity is Directory) {
            try {
              entity.listSync();
            } catch (ex) {
              print('catch: ${entity.path}, $ex');
              files.remove(entity);
            }
          }
        }
        files.sort((FileSystemEntity a, FileSystemEntity b) {
          if (a is Directory && b is File) return -1;
          if (a is File && b is Directory) return 1;
          return a.path.compareTo(b.path);
        });
      }
    
      Widget buildList() {
        if (parent == null) return ListView();
        bool isRoot = parent.path == parent.parent.path;
        return ListView.builder(
          itemBuilder: (context, i) {
            if (i.isOdd)
              return Divider(
                height: 4.0,
              );
            final index = isRoot ? i ~/ 2 : i ~/ 2 - 1;
            return buildRow(index);
          },
          itemCount: isRoot ? files.length * 2 : (files.length + 1) * 2,
          controller: controller,
        );
      }
    
      Widget buildRow(int index) {
        if (index == -1) return getRootTile();
        FileSystemEntity file = files[index];
    
        if (file is Directory) return getDirectoryTile(file);
        if (file is File) return getFileTile(file);
        if (file is Link)
          return Container(
            height: 0.0,
          );
        return Container(
          height: 0.0,
        );
      }
    
      Widget getRootTile() {
        return ListTile(
          title: Text('../'),
          trailing: Icon(Icons.keyboard_backspace),
          onTap: () {
            setState(() {
              parent = parent.parent;
              List<FileSystemEntity> rootList = parent.listSync();
              files.clear();
              files.addAll(rootList);
              sortFiles();
            });
          },
        );
      }
    
      Widget getDirectoryTile(Directory dir) {
        return ListTile(
          title: Text(dir.path.split('/').last),
          trailing: Icon(
            Icons.folder_open,
            color: Colors.grey,
          ),
          onTap: () {
            setState(() {
              parent = dir;
              files.clear();
              files.addAll(dir.listSync());
              sortFiles();
            });
          },
        );
      }
    
      Widget getFileTile(File file) {
        bool isSaved = savedFiles.map((file) => file.path).contains(file.path);
        final List<String> extensions = <String>[
          "MP3",
          "WAV",
          "AAC",
          "WMA",
          "AMR",
          "OGG",
          "MIDI"
        ];
        bool isRightType =
            extensions.contains(file.path.split('.').last.toUpperCase());
        return ListTile(
          title: Text(file.path.split('/').last),
          trailing: isRightType
              // ignore: missing_required_param
              ? IconButton(
                  icon: Icon(
                    isSaved ? Icons.check_box : Icons.check_box_outline_blank,
                    color: isSaved ? Colors.blueGrey : Colors.grey,
                  ),
                )
              : null,
          onTap: () {
            setState(() {
              if (isSaved) {
                savedFiles.remove(file);
              } else {
                savedFiles.add(file);
              }
            });
          },
        );
      }
    
      void apply() async {
        final List<Track> list = List();
        list.addAll(savedFiles.map((file) => Track(file.path)));
        Navigator.of(context).pop(list);
      }
    
      Future<String> get localPath async {
        final directory = await getApplicationDocumentsDirectory();
        return directory.path;
      }
    }
    

    在我的情况下,我显示所有文件,但只有音频是可选的(带有复选框)

    【讨论】:

    • 我不懂术语 savedFiles
    • 你的问题没有必要。在我的代码中,它是一个列表,我在其中存储选定的文件,并根据此列表将复选框设置为选中或未选中
    • 你能展示你的完整代码吗,因为我不明白你的代码是怎样的
    • 如果您能帮我列出 sd 卡中的歌曲,我将不胜感激
    • 更新 - 显示文件树和选择音频的完整小部件
    【解决方案2】:

    如果您说的是能够识别文件扩展名,那么您首先需要安装 Path 并导入它:

    import 'package:path/path.dart' as p;
    

    然后检查一下:

    String _extension = p.extension(_someFile).split('?').first;
    

    【讨论】:

    • 你没看懂问题
    • var tempPath= someList.path; tempPath.endsWith(".mp4");
    【解决方案3】:

    我建议你阅读Android Studio | Files的文档

    • 您可以使用 fileList() 来获取 ArrayList
    • 进一步,使用 for 循环获取名称和路径 -> file.getName() | file.getPath()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-04
      • 1970-01-01
      • 2018-11-21
      • 1970-01-01
      • 2017-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多