Показать все изображения из каталога в список в Flutter
Мне было интересно, если есть способ, которым я могу отобразить все изображения или файлы в определенном каталоге, расположенном на мобильном устройстве пользователя, в список / массив во флаттере, чтобы я мог использовать в ListView.
Спасибо, любая помощь приветствуется.
PS: я хотел попробовать с path_provider, но не знал как.
4 ответа
Я смог найти решение.
Мне пришлось работать с MethodChannels в других, чтобы добиться этого.
После написания Java-кода для получения списка файлов я вошел во флаттер через канал
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 MethodChannel
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
Я работаю над приложением, которое использует локальное хранилище / каталог приложений.
Проведя пять дней, я получил решение...
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"))
в вышеупомянутом коде.
I have done something similar to that, In one of my flutter Application, i am getting the list of the images Urls from downloads directory and showing them in staggered list.
Retrieving of images URLs from the downloads directory is done with the help of MethodChannel. Also, don't forget to add the required package to pubspec.yaml file in flutter
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;
});
}
}
Here is the code for 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;
}
}
The above code contains some extra functionality you can remove them as per your requirement.
Использовать
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.