local_image_pager
A plugin for showing your device's local images with pagination.
Features
- Get total number of images in your device.
- Fetch local images with pagination.
Getting started
In the pubspec.yaml
of your flutter project, add the following dependency:
dependencies:
...
local_image_pager:
In your library add the following import:
import 'package:local_image_pager/local_image_pager.dart';
For help getting started with Flutter, view the online documentation.
How to use
See the example below. For more info, check the example project.
@override
Widget build(BuildContext context) {
// Calculate the thumbnail's size first to improve performance.
final itemSize = ((MediaQuery.of(context).size.width -
spacing * (cross_axis_count - 1) - horizontal_padding * 2) /
cross_axis_count);
final cacheSize = (itemSize * 1.5).round();
final pager = LocalImagePager();
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Local images pager'),
),
body: Column(children: [
const SizedBox(height: 100,
child: Center(child: Text('Your own widget here.', style: TextStyle(fontSize: 20, color: Colors.blue, fontWeight: FontWeight.bold),),)),
Expanded(child: FutureBuilder(
future: _initPermissions,
builder: (context, snapshot) {
if (snapshot.hasData) {
if (snapshot.data) {
return FutureBuilder(
future: LocalImagePager.totalNumber,
builder: (context, snapshot) {
if (snapshot.hasData) {
final count = snapshot.data;
if (count == 0) {
return const Center(
child: Text('No images'),
);
} else {
return GridView.builder(
padding: const EdgeInsets.symmetric(horizontal: horizontal_padding),
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: cross_axis_count,
mainAxisSpacing: spacing,
crossAxisSpacing: spacing,
),
itemCount: count,
itemBuilder: (context, index) =>
_itemBuilder(
pager, count, index, itemSize, cacheSize));
}
} else if (snapshot.hasError) {
return Center(
child: Text(
snapshot.error.toString(),
style: const TextStyle(color: Colors.red),
),
);
} else {
return const Center(
child: CircularProgressIndicator());
}
},
);
} else {
return Column(
children: [
const Text(
'Permission not granted, try again.',
style: const TextStyle(color: Colors.red),
),
FlatButton(
onPressed: () {
setState(() {});
},
child: const Text('OK'))
],
);
}
} else if (snapshot.hasError) {
return Center(
child: Text(
snapshot.error.toString(),
style: const TextStyle(color: Colors.red),
),
);
} else {
return const Center(child: CircularProgressIndicator());
}
},
),)
])),
);
}
Widget _itemBuilder(
LocalImagePager paginate, int totalNumber, int index, double itemSize, int cacheSize) {
_load(paginate, totalNumber, index);
return FutureBuilder(
future: _completers[index].future,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Image.file(
File(snapshot.data),
fit: BoxFit.cover,
height: itemSize,
cacheHeight: cacheSize,
);
} else if (snapshot.hasError) {
print('_itemBuilder:error:${snapshot.error.toString()}');
return const SizedBox(
width: 0,
height: 0,
);
} else {
return const SizedBox(
width: 0,
height: 0,
);
}
},
);
}
_load(LocalImagePager paginate, int count, int itemIndex) async {
if (itemIndex % per_load_count != 0) {
return;
}
if (itemIndex >= _completers.length) {
final toLoad = min(count - itemIndex, per_load_count);
if (toLoad > 0) {
_completers.addAll(List.generate(toLoad, (index) {
return Completer();
}));
try {
final images =
await paginate.latestImages(itemIndex, itemIndex + toLoad - 1);
images.asMap().forEach((index, item) {
_completers[itemIndex + index].complete(item);
});
} catch (e) {
print('_load:error:${e.toString()}');
_completers
.sublist(itemIndex, itemIndex + toLoad)
.forEach((completer) {
completer.completeError(e);
});
}
}
}
}
Permissions
Applications using this plugin require the following user permissions.
iOS
Add the following key to your Info.plist file, located in <project root>/ios/Runner/Info.plist
:
NSPhotoLibraryUsageDescription
- describe why your app needs permission for the photo library. This is called Privacy - Photo Library Usage Description in the visual editor. This permission is required for the app to read the image and album information.
Android
Add the storage permission to your AndroidManifest.xml file, located in <project root>/android/app/src/main/AndroidManifest.xml
:
android.permission.READ_EXTERNAL_STORAGE
- this allows the app to query and read the image and album information.