[英]How to display images from a external storage path in flutter?
Im basically new to flutter.我基本上不熟悉颤振。 I want to display Images from specific path like "Storage/WhatsApp/Media/".
我想从“存储/WhatsApp/媒体/”等特定路径显示图像。 I want to show all the images in grid view.
我想在网格视图中显示所有图像。 How can i acheive this in flutter.
我怎样才能在颤振中实现这一点。 I have seen many examples but everyone is using assets folder.
我看过很多例子,但每个人都在使用资产文件夹。 This is the code for getting the path.
这是获取路径的代码。 How to display them in grid view?
如何在网格视图中显示它们?
Future<String> get localpath async
{
final dir=await getExternalStorageDirectory();
return dir.path;
}
Future<File> get localfile async{
final path=await localpath;
return File('$path/WhatsApp/Media/WhatsApp Images');
}
Future<String> readData() async{
try{
final file=await localfile;
String image_path=await file.readAsString();
return image_path;
}
catch(e) {return e.toString();}
}
Now since i got the path how to display images in gridview?现在既然我知道了如何在 gridview 中显示图像的路径? Should i use gridview.builder?
我应该使用 gridview.builder 吗?
提供您的存储路径,您可以显示图像
Image.file(File(imagePath);
I've tried following a similar approach as yours for fetching files by using path_provider
.我尝试采用与您类似的方法来使用
path_provider
获取文件。 However, the plugin is only able to fetch the app's directory, even when using getExternalStorageDirectory()
.但是,即使使用
getExternalStorageDirectory()
,该插件也只能获取应用程序的目录。 This behavior is also pointed out in this Stack Overflow post .这篇Stack Overflow 帖子中也指出了这种行为。
Instead, I've used ext_storage
to access the device's storage.相反,我使用
ext_storage
来访问设备的存储。
This sample app demonstrates fetching files on your device's /Download folder using ext_storage
, handling permissions using permission_handler
, file extension check, and displaying images from path on a GridView.此示例应用程序演示了使用
ext_storage
获取设备 /Download 文件夹中的文件、使用ext_storage
处理permission_handler
、文件扩展名检查以及从 GridView 上的路径显示图像。
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:ext_storage/ext_storage.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future _futureGetPath;
List<dynamic> listImagePath = List<dynamic>();
var _permissionStatus;
@override
void initState() {
super.initState();
_listenForPermissionStatus();
// Declaring Future object inside initState() method
// prevents multiple calls inside stateful widget
_futureGetPath = _getPath();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Expanded(
flex: 1,
child: FutureBuilder(
future: _futureGetPath,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
var dir = Directory(snapshot.data);
print('permission status: $_permissionStatus');
if (_permissionStatus) _fetchFiles(dir);
return Text(snapshot.data);
} else {
return Text("Loading");
}
},
),
),
Expanded(
flex: 19,
child: GridView.count(
primary: false,
padding: const EdgeInsets.all(20),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
crossAxisCount: 3,
children: _getListImg(listImagePath),
),
)
],
),
);
}
// Check for storage permission
void _listenForPermissionStatus() async {
final status = await Permission.storage.request().isGranted;
// setState() triggers build again
setState(() => _permissionStatus = status);
}
// Get storage path
// https://pub.dev/documentation/ext_storage/latest/
Future<String> _getPath() {
return ExtStorage.getExternalStoragePublicDirectory(
ExtStorage.DIRECTORY_DOWNLOADS);
}
_fetchFiles(Directory dir) {
List<dynamic> listImage = List<dynamic>();
dir.list().forEach((element) {
RegExp regExp =
new RegExp("\.(gif|jpe?g|tiff?|png|webp|bmp)", caseSensitive: false);
// Only add in List if path is an image
if (regExp.hasMatch('$element')) listImage.add(element);
setState(() {
listImagePath = listImage;
});
});
}
List<Widget> _getListImg(List<dynamic> listImagePath) {
List<Widget> listImages = List<Widget>();
for (var imagePath in listImagePath) {
listImages.add(
Container(
padding: const EdgeInsets.all(8),
child: Image.file(imagePath, fit: BoxFit.cover),
),
);
}
return listImages;
}
}
Note that this only covers the basics of displaying images on a GridView.请注意,这仅涵盖了在 GridView 上显示图像的基础知识。 To scale, I suggest following this guide on performance best practices .
为了扩展,我建议遵循这个性能最佳实践指南。
localfile
returning async value so need to use it using await and then update it using setState()
localfile
返回异步值,因此需要使用 await 使用它,然后使用setState()
更新它
Example:例子:
Future<File> get localfile async {
final path= await localpath;
return File('$path/WhatsApp/Media/WhatsApp Images');
}
File file = await localfile;
setState(() {});
Show storage file using Image.file
widget使用
Image.file
小部件显示存储文件
Image.file(file, fit: BoxFit.cover,)
Note: file object would be null initially, as it is fetching async value, so for that use ternary operation and show progress indicator or any other widget.注意:文件对象最初为空,因为它正在获取异步值,因此为此使用三元操作并显示进度指示器或任何其他小部件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.