android - 如何在 Flutter 中读取音频扩展并显示在 ListView 中?

标签 android dart flutter

如何在 Flutter 中实现从 SD 卡读取音频文件并将其显示到 ListView 的功能?

最佳答案

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

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;
  }
}

在我的例子中,我显示了所有文件,但只有音频是可选的(带复选框)

关于android - 如何在 Flutter 中读取音频扩展并显示在 ListView 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53550713/

相关文章:

android - ProGuard - 仅混淆和缩小包?

dart - 带有列表的空感知运算符

java - 如何在 xml 文件中查找 ID?

flutter - Flutter CustomPainter 类中的电池电量指示器颠倒绘制

flutter - 由于堆叠屏幕 flutter ,Snackbar 显示两次,我该如何避免?

Flutter:如何使按钮扩展到其父级的大小?

Flutter - 使用相同的提供者更新下拉列表并将数据发送到另一个小部件

android - 在 flutter 中具有拖动效果的滚动条

android - 换行符和制表符未正确显示

java - 有没有办法更改 Android Google Map API 的 map 数据?