【问题标题】:Display all images in a directory to a list in Flutter在 Flutter 中将目录中的所有图像显示到列表中
【发布时间】:2019-02-14 13:53:22
【问题描述】:

我想知道是否有一种方法可以将位于用户移动设备中的特定目录中的所有图像或文件显示到颤动的列表/数组中,以便我可以在 ListView 中使用。

谢谢,欢迎任何帮助。

PS:我想试试 path_provider 但不知道怎么做。

【问题讨论】:

    标签: ios flutter dart dart-sdk


    【解决方案1】:

    我正在开发使用本地存储/应用程序目录的应用程序。

    花了五天后,我得到了解决方案......

    import 'dart:async';
    import 'dart:io';
    import 'package:flutter/material.dart';
    import 'package:flutter/widgets.dart';
    import 'package:path/path.dart';
    import 'package:path_provider/path_provider.dart';
    
    final Directory _photoDir = new Directory(
        '/storage/emulated/0/Android/data/com.eclixtech.doc_scanner/files/CroppedImages');
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Document Scanner',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: ImageCapture(),
        );
      }
    }
    
    class ImageCapture extends StatefulWidget {
      @override
       _ImageCaptureState createState() => _ImageCaptureState();
    }
    
    class _ImageCaptureState extends State<ImageCapture> {
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Doc Scanner'),
          ),
          body: Container(
            child: FutureBuilder(
              builder: (context, status) {
                return ImageGrid(directory: _photoDir);
              },
            ),
          ),
        );
      }
    }
    class ImageGrid extends StatelessWidget {
      final Directory directory;
    
      const ImageGrid({Key key, this.directory}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        var refreshGridView;
        var imageList = directory
            .listSync()
            .map((item) => item.path)
            .where((item) => item.endsWith(".jpg"))
            .toList(growable: false);
        return GridView.builder(
          itemCount: imageList.length,
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 3, childAspectRatio: 3.0 / 4.6),
          itemBuilder: (context, index) {
            File file = new File(imageList[index]);
            String name = file.path.split('/').last;
            return Card(
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(8.0),
              ),
              child: Padding(
                padding: const EdgeInsets.all(5.0),
                child: InkWell(
                  onTap: () => {
                    refreshGridView =
                    Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return ImageEditClass(
                    imagepath: imageList[index],
                  );
                })).then((refreshGridView) {
                  if (refreshGridView != null) {
                    build(context);
                  }
                }).catchError((er) {
                  print(er);
                }),
                  },
                   child: Padding(
                     padding: new EdgeInsets.all(4.0),
                     child: Image.file(
                       File(imageList[index]),
                       fit: BoxFit.cover,
                     ),
                   ),
                ),
              ),
            );
          },
        );
      }
    }
    

    您可以在此处提及图片的扩展名(.jpg、.png 等)。

    .where((item) => item.endsWith(".jpg"))
    

    在上述代码中。

    【讨论】:

      【解决方案2】:

      我找到了解决办法。

      我必须与 MethodChannels 合作才能实现这一目标。

      写完获取文件列表的java代码后,我通过一个channel传入flutter

      获取文件的Java方法

      private List<String> getImages(){
              String path = Environment.getExternalStorageDirectory().toString();
      
              List<String> imgs = new ArrayList<String>();
              File directory = new File(path);
              List<String> files = Arrays.asList(directory.list());
      
              imgs = files;
      
              return imgs;
          }
      

      Java 方法通道

      new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
                    (call, result) -> {
                        if (call.method.equals("getImages")) {
                            List<String> imgs = getImages();
                            if (imgs.size() <= 0) {
                                result.error("Empty", "No Images.", null);
                            } else {
                                result.success(imgs);                      }
                        } else {
                            result.notImplemented();
                        }
      
                    });
      

      飞镖代码

       Future<void> _getImages() async {
          List images;
          try {
            final List result = await platform.invokeMethod('getImages');
            images = result;
          } on PlatformException catch (e) {
            print("Error");
          }
      
          setState(() {
            imgs = images;
          });
        }
      

      完整的源代码可在Github获得

      【讨论】:

      • getImages() 存在问题,它会返回目录中除图像以外的所有文件 URL
      【解决方案3】:

      我做了类似的事情,在我的一个颤振应用程序中,我从下载目录中获取图像 URL 列表并将它们显示在交错列表中。

      在 MethodChannel 的帮助下从下载目录中检索图像 URL。另外,不要忘记在flutter中将所需的包添加到pubspec.yaml文件中

      import 'package:flutter/material.dart';
      import 'dart:async';
      import 'dart:core';
      import 'dart:io';
      import 'package:flutter/services.dart';
      import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
      import 'package:denphy_wallpapers/main_image_screen/fullscreen_wallpaper.dart';
      
      class Downloads extends StatefulWidget {
        static final String id = 'downloads';
      
        @override
        _DownloadsState createState() => _DownloadsState();
      }
      
      class _DownloadsState extends State<Downloads> {
        static const platform = const MethodChannel('samples.flutter.dev/battery');
        List images;
      
        @override
        void initState() {
          // TODO: implement initState
          super.initState();
      
          _getImages();
        }
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: new AppBar(
              title: new Text(
                "Downloads",
                style: TextStyle(
                    fontFamily: 'Welcome', color: Colors.blue, fontSize: 32.0),
              ),
              centerTitle: true,
              backgroundColor: Colors.white,
            ),
            body: images != null
                ? new StaggeredGridView.countBuilder(
                    padding: const EdgeInsets.all(8.0),
                    crossAxisCount: 4,
                    itemCount: images.length,
                    itemBuilder: (context, i) {
                      String imgPath = images[i];
                      print(imgPath);
                      return new Material(
                        elevation: 8.0,
                        borderRadius: new BorderRadius.all(new Radius.circular(8.0)),
                        child: new InkWell(
                          onTap: () {
                            //print(imageName);
                            Navigator.push(
                                context,
                                new MaterialPageRoute(
                                    builder: (context) =>
                                        new FullScreenImagePage(imgPath, "")));
                          },
                          child: new Hero(
                            tag: imgPath,
                            child: ClipRRect(
                                borderRadius: BorderRadius.circular(8.0),
                                child: Image.file(
                                  File(imgPath),
                                  fit: BoxFit.cover,
                                )),
                          ),
                        ),
                      );
                    },
                    staggeredTileBuilder: (i) =>
                        new StaggeredTile.count(2, i.isEven ? 2 : 3),
                    mainAxisSpacing: 8.0,
                    crossAxisSpacing: 8.0,
                  )
                : new Center(
                    child: new CircularProgressIndicator(),
                  ),
          );
        }
      
        //Check the MainActivity.java
        Future<void> _getImages() async {
          print('inside get images>>>>>>>>>>>>');
          List imgs;
          try {
            final List result = await platform.invokeMethod('getImages');
            imgs = result;
            for (String i in result) {
              print('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>$i');
            }
          } on PlatformException catch (e) {
            print("Error");
          }
      
          setState(() {
            images = imgs;
          });
        }
      }
      
      

      这是 MainActivity 的代码。

      import android.os.Bundle;
      import androidx.annotation.RequiresApi;
      import android.Manifest;
      import android.app.WallpaperManager;
      import android.content.ActivityNotFoundException;
      import android.content.Intent;
      import android.content.pm.PackageManager;
      import android.graphics.Bitmap;
      import android.graphics.BitmapFactory;
      import android.graphics.drawable.BitmapDrawable;
      import android.net.Uri;
      import android.os.Build;
      import android.os.Bundle;
      import android.os.Environment;
      import android.util.Log;
      import android.view.View;
      import android.widget.Button;
      import android.widget.ImageView;
      import android.widget.Toast;
      import java.io.File;
      import java.io.IOException;
      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.List;
      import java.io.FilenameFilter;
      import io.flutter.app.FlutterActivity;
      import io.flutter.plugins.GeneratedPluginRegistrant;
      import io.flutter.plugin.common.MethodCall;
      import io.flutter.plugin.common.MethodChannel;
      import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
      import io.flutter.plugin.common.MethodChannel.Result;
      
      import android.content.ContextWrapper;
      import android.content.Intent;
      import android.content.IntentFilter;
      import android.os.BatteryManager;
      import android.os.Build.VERSION;
      import android.os.Build.VERSION_CODES;
      import android.os.Bundle;
      
      public class MainActivity extends FlutterActivity {
          private static final String TAG = "MainActivity";
          private static final String CHANNEL = "samples.flutter.dev/battery";
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              GeneratedPluginRegistrant.registerWith(this);
      
              new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
                      new MethodCallHandler() {
                          @Override
                          public void onMethodCall(MethodCall call, Result result) {
                               if(call.method.equals("getImages")){
                                  android.util.Log.e(TAG, "onMethodCall: "+"get Images" );
                                  List<String> imgs = getImages();
                                  if (imgs.size() <= 0) {
                                      result.error("Empty", "No Images.", null);
                                  } else {
                                      result.success(imgs);
                                  }
                              }
                              else {
                                  result.notImplemented();
                              }
                          }
                      }
              );
      
          }
      
      
          private List<String> getImages() {
              File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString()+"/denphy walls/");
              folder.mkdirs();
              File[] allFiles = folder.listFiles(new FilenameFilter() {
                  public boolean accept(File dir, String name) {
                      return (name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".png"));
                  }
              });
              List<String> item = new ArrayList<String>();
              for (File file : allFiles) {
                  item.add(file + "");
              }
              return item;
          }
      }
      
      

      上面的代码包含一些额外的功能,您可以根据需要删除它们。

      【讨论】:

        【解决方案4】:

        使用getApplicationDocumentsDirectory() 从应用存储中获取值。

        Future<String> get _getLocalPath async {
            final directory = await getApplicationDocumentsDirectory();
            final path = directory.path;
            final String filePath = '$path/folderName/';
            return filePath;
          }
        

        FileSystemEntity,提供文件路径,可用于显示图片。

            String _localPath = await _getLocalPath;
            final savedDir = Directory(_localPath);
            bool hasExisted = await savedDir.exists();
            if (!hasExisted) {
              savedDir.create();
            }
            List<FileSystemEntity> files = savedDir.listSync(); /// iterate the list to get individual entry.
        

        【讨论】:

          猜你喜欢
          • 2020-01-21
          • 2012-06-12
          • 1970-01-01
          • 2012-07-02
          • 2021-11-04
          • 2013-04-29
          • 1970-01-01
          • 2019-10-25
          • 2019-11-07
          相关资源
          最近更新 更多