Skip to main content

Flutter FilePicker Example

The FilePicker widget, provides a simple way to pick files from the device's storage.

In this article, we will explore how to use the FilePicker widget in Flutter to pick files from the device's storage and display them in our Flutter app.

Using the FilePicker Widget in Flutter

The FilePicker widget is part of the flutter_file_picker package, which we need to add to our project's dependencies. To do so, we need to add the following line to our project's pubspec.yaml file:

dependencies:
flutter_file_picker: ^3.0.0

After adding the package to our project, we need to import it in the Dart file where we want to use the FilePicker widget:

import 'package:flutter_file_picker/flutter_file_picker.dart';

With the package imported, we can now use the FilePicker widget in our Flutter app. The widget provides two ways to pick files from the device's storage: using a file picker dialog or using a file picker button.

Using a File Picker Dialog

To use a file picker dialog, we first need to create a button that will trigger the dialog. We can use the following code to create a button that will display a file picker dialog:

ElevatedButton(
onPressed: () async {
final result = await FilePicker.platform.pickFiles();
if (result != null) {
// Do something with the picked files
}
},
child: Text('Pick Files'),
)

The code above creates an ElevatedButton that, when pressed, will display a file picker dialog. The pickFiles method returns a FilePickerResult object that contains information about the picked files, including their paths and names.

Using a File Picker Button

Alternatively, we can use a file picker button, which is a pre-built widget that displays a button and the name of the picked file. We can use the following code to create a file picker button:

FilePickerResult? filePickerResult;

FilePickerButton(
child: Text('Pick File'),
onFilePicked: (result) {
setState(() {
filePickerResult = result;
});
},
)

The code above creates a FilePickerButton that, when pressed, will display a file picker dialog. When a file is picked, the onFilePicked callback function is called, which sets the filePickerResult variable to the picked file's information. We can use this information to display the picked file's name or path.

More Examples

Being able to consume files from an android part device is part of any native app development. This process is quite easy when in native development using Kotlin/Java, but probably even easier with Flutter, courtesy of multiple packages available to use for free.

This tutorial will explore examples and packages for picking files in flutter.

(a). file_picker example

file_picker is a package that allows you to use a native file explorer to pick single or multiple absolute file paths, with extension filtering support.

Here are the supported features:

  • Uses OS default native pickers
  • Pick files using custom format filtering — you can provide a list of file extensions (pdf, svg, zip, etc.)
  • Pick files from cloud files (GDrive, Dropbox, iCloud)
  • Single or multiple file picks
  • Different default type filtering (media, image, video, audio or any)
  • Picking directories
  • Flutter Web
  • Desktop (MacOS, Linux and Windows through Flutter Go)
  • Load file data immediately into memory (Uint8List) if needed;

Let's look at how use this package with a step by step example.

Here is what will be created in the example:

Flutter FilePicker Example

Step 1: Install it

You start by installing. Add the file_picker in your pubspec.yaml file:


dependencies:
file_picker: ^3.0.4

Then flutter pub get to fetch it.

Step 2: Write code

Then start by importing the package:

import 'package:file_picker/file_picker.dart';

Then if you want to pick a single file you can use the following code:

FilePickerResult? result = await FilePicker.platform.pickFiles();
if(result != null) {
File file = File(result.files.single.path);
} else {
// User canceled the picker
}

If you want to pick multiple files use the following code:

FilePickerResult? result = await FilePicker.platform.pickFiles(allowMultiple: true);
if(result != null) {
List<File> files = result.paths.map((path) => File(path)).toList();
} else {
// User canceled the picker
}

Sometimes you wish to pick only a certain type of files. Say you want only to pick jpg images, pdf files as well as ms word documents, here is the code you can use:

FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'pdf', 'doc'],
);

So now that you've picked your file, you actually want to use that picked file in your code. Let's say you want to print the details like name and size. Here is the code you use;

FilePickerResult? result = await FilePicker.platform.pickFiles();
if(result != null) {
PlatformFile file = result.files.first;
print(file.name);
print(file.bytes);
print(file.size);
print(file.extension);
print(file.path);
} else {
// User canceled the picker
}

Or let's say you want to pick a single file and load it to firebase cloud storage, here is a sample code:

FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
Uint8List fileBytes = result.files.first.bytes;
String fileName = result.files.first.name;
// Upload file
await FirebaseStorage.instance.ref('uploads/$fileName').putData(fileBytes);
}

Full Example

Here is a full example of how to use this package:

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class FilePickerDemo extends StatefulWidget {

_FilePickerDemoState createState() => _FilePickerDemoState();
}
class _FilePickerDemoState extends State<FilePickerDemo> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
String? _fileName;
List<PlatformFile>? _paths;
String? _directoryPath;
String? _extension;
bool _loadingPath = false;
bool _multiPick = false;
FileType _pickingType = FileType.any;
TextEditingController _controller = TextEditingController();

void initState() {
super.initState();
_controller.addListener(() => _extension = _controller.text);
}
void _openFileExplorer() async {
setState(() => _loadingPath = true);
try {
_directoryPath = null;
_paths = (await FilePicker.platform.pickFiles(
type: _pickingType,
allowMultiple: _multiPick,
allowedExtensions: (_extension?.isNotEmpty ?? false)
? _extension?.replaceAll(' ', '').split(',')
: null,
))
?.files;
} on PlatformException catch (e) {
print("Unsupported operation" + e.toString());
} catch (ex) {
print(ex);
}
if (!mounted) return;
setState(() {
_loadingPath = false;
print(_paths!.first.extension);
_fileName =
_paths != null ? _paths!.map((e) => e.name).toString() : '...';
});
}
void _clearCachedFiles() {
FilePicker.platform.clearTemporaryFiles().then((result) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: result! ? Colors.green : Colors.red,
content: Text((result
? 'Temporary files removed with success.'
: 'Failed to clean temporary files')),
),
);
});
}
void _selectFolder() {
FilePicker.platform.getDirectoryPath().then((value) {
setState(() => _directoryPath = value);
});
}

Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: const Text('File Picker example app'),
),
body: Center(
child: Padding(
padding: const EdgeInsets.only(left: 10.0, right: 10.0),
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 20.0),
child: DropdownButton<FileType>(
hint: const Text('LOAD PATH FROM'),
value: _pickingType,
items: <DropdownMenuItem<FileType>>[
DropdownMenuItem(
child: const Text('FROM AUDIO'),
value: FileType.audio,
),
DropdownMenuItem(
child: const Text('FROM IMAGE'),
value: FileType.image,
),
DropdownMenuItem(
child: const Text('FROM VIDEO'),
value: FileType.video,
),
DropdownMenuItem(
child: const Text('FROM MEDIA'),
value: FileType.media,
),
DropdownMenuItem(
child: const Text('FROM ANY'),
value: FileType.any,
),
DropdownMenuItem(
child: const Text('CUSTOM FORMAT'),
value: FileType.custom,
),
],
onChanged: (value) => setState(() {
_pickingType = value!;
if (_pickingType != FileType.custom) {
_controller.text = _extension = '';
}
})),
),
ConstrainedBox(
constraints: const BoxConstraints.tightFor(width: 100.0),
child: _pickingType == FileType.custom
? TextFormField(
maxLength: 15,
autovalidateMode: AutovalidateMode.always,
controller: _controller,
decoration:
InputDecoration(labelText: 'File extension'),
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.none,
)
: const SizedBox(),
),
ConstrainedBox(
constraints: const BoxConstraints.tightFor(width: 200.0),
child: SwitchListTile.adaptive(
title:
Text('Pick multiple files', textAlign: TextAlign.right),
onChanged: (bool value) =>
setState(() => _multiPick = value),
value: _multiPick,
),
),
Padding(
padding: const EdgeInsets.only(top: 50.0, bottom: 20.0),
child: Column(
children: <Widget>[
ElevatedButton(
onPressed: () => _openFileExplorer(),
child: const Text("Open file picker"),
),
ElevatedButton(
onPressed: () => _selectFolder(),
child: const Text("Pick folder"),
),
ElevatedButton(
onPressed: () => _clearCachedFiles(),
child: const Text("Clear temporary files"),
),
],
),
),
Builder(
builder: (BuildContext context) => _loadingPath
? Padding(
padding: const EdgeInsets.only(bottom: 10.0),
child: const CircularProgressIndicator(),
)
: _directoryPath != null
? ListTile(
title: const Text('Directory path'),
subtitle: Text(_directoryPath!),
)
: _paths != null
? Container(
padding: const EdgeInsets.only(bottom: 30.0),
height:
MediaQuery.of(context).size.height * 0.50,
child: Scrollbar(
child: ListView.separated(
itemCount:
_paths != null && _paths!.isNotEmpty
? _paths!.length
: 1,
itemBuilder:
(BuildContext context, int index) {
final bool isMultiPath =
_paths != null && _paths!.isNotEmpty;
final String name = 'File $index: ' +
(isMultiPath
? _paths!
.map((e) => e.name)
.toList()[index]
: _fileName ?? '...');
final path = _paths!
.map((e) => e.path)
.toList()[index]
.toString();
return ListTile(
title: Text(
name,
),
subtitle: Text(path),
);
},
separatorBuilder:
(BuildContext context, int index) =>
const Divider(),
)),
)
: const SizedBox(),
),
],
),
),
)),
),
);
}
}

Reference

Find download link below:

No.Link
1.Download full code
2.Browse code

Conclusion

The FilePicker widget in Flutter provides a simple and easy way to pick files from the device's storage. We can use a file picker dialog or a file picker button to pick one or more files, and then use the picked files' information in our Flutter app. With the help of the flutter_file_picker package, we can easily integrate the FilePicker widget into our Flutter app and provide a great user experience.