improved widget constructors and main future builder
This commit is contained in:
parent
3c9813c942
commit
f091ad1955
7 changed files with 86 additions and 54 deletions
|
@ -6,12 +6,13 @@ class OutlinedText extends StatelessWidget {
|
||||||
final double outlineWidth;
|
final double outlineWidth;
|
||||||
final Color outlineColor;
|
final Color outlineColor;
|
||||||
|
|
||||||
OutlinedText(
|
const OutlinedText(
|
||||||
this.data, {
|
this.data, {
|
||||||
|
Key key,
|
||||||
this.style,
|
this.style,
|
||||||
@required this.outlineWidth,
|
@required this.outlineWidth,
|
||||||
@required this.outlineColor,
|
@required this.outlineColor,
|
||||||
});
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
|
@ -7,7 +7,7 @@ class FullscreenOverlay extends StatefulWidget {
|
||||||
final List<Map> entries;
|
final List<Map> entries;
|
||||||
final int index;
|
final int index;
|
||||||
|
|
||||||
FullscreenOverlay({this.entries, this.index});
|
const FullscreenOverlay({Key key, this.entries, this.index}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _FullscreenOverlayState();
|
State<StatefulWidget> createState() => _FullscreenOverlayState();
|
||||||
|
|
|
@ -10,7 +10,11 @@ class ImageFullscreenPage extends StatefulWidget {
|
||||||
final List<Map> entries;
|
final List<Map> entries;
|
||||||
final String initialUri;
|
final String initialUri;
|
||||||
|
|
||||||
ImageFullscreenPage({this.entries, this.initialUri});
|
const ImageFullscreenPage({
|
||||||
|
Key key,
|
||||||
|
this.entries,
|
||||||
|
this.initialUri,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ImageFullscreenPageState createState() => ImageFullscreenPageState();
|
ImageFullscreenPageState createState() => ImageFullscreenPageState();
|
||||||
|
|
|
@ -16,7 +16,7 @@ class MyApp extends StatelessWidget {
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
brightness: Brightness.dark,
|
brightness: Brightness.dark,
|
||||||
accentColor: Colors.amberAccent,
|
accentColor: Colors.amberAccent,
|
||||||
scaffoldBackgroundColor: Colors.grey[900]
|
scaffoldBackgroundColor: Colors.grey[900],
|
||||||
),
|
),
|
||||||
home: HomePage(),
|
home: HomePage(),
|
||||||
);
|
);
|
||||||
|
@ -29,18 +29,13 @@ class HomePage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _HomePageState extends State<HomePage> {
|
class _HomePageState extends State<HomePage> {
|
||||||
List<Map> imageEntryList;
|
Future<List<Map>> _entryListLoader;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
imageCache.maximumSizeBytes = 100 * 1024 * 1024;
|
imageCache.maximumSizeBytes = 100 * 1024 * 1024;
|
||||||
getImageEntries();
|
_entryListLoader = ImageFetcher.getImageEntries();
|
||||||
}
|
|
||||||
|
|
||||||
getImageEntries() async {
|
|
||||||
imageEntryList = await ImageFetcher.getImageEntries();
|
|
||||||
setState(() {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -49,11 +44,17 @@ class _HomePageState extends State<HomePage> {
|
||||||
// fake app bar so that content is safe from status bar, even though we use a SliverAppBar
|
// fake app bar so that content is safe from status bar, even though we use a SliverAppBar
|
||||||
appBar: FakeAppBar(),
|
appBar: FakeAppBar(),
|
||||||
body: Container(
|
body: Container(
|
||||||
child: imageEntryList == null
|
child: FutureBuilder(
|
||||||
? Center(
|
future: _entryListLoader,
|
||||||
child: CircularProgressIndicator(),
|
builder: (futureContext, AsyncSnapshot<List<Map>> snapshot) {
|
||||||
)
|
if (snapshot.connectionState == ConnectionState.done && !snapshot.hasError) {
|
||||||
: ThumbnailCollection(imageEntryList),
|
return ThumbnailCollection(entries: snapshot.data);
|
||||||
|
}
|
||||||
|
return Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
);
|
);
|
||||||
|
|
|
@ -41,7 +41,7 @@ class ImageFetcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
// return map with: 'aperture' 'exposureTime' 'focalLength' 'iso'
|
// return map with: 'aperture' 'exposureTime' 'focalLength' 'iso'
|
||||||
static Future<Map> getOverlayMetadata (String path) async {
|
static Future<Map> getOverlayMetadata(String path) async {
|
||||||
try {
|
try {
|
||||||
final result = await platform.invokeMethod('getOverlayMetadata', <String, dynamic>{
|
final result = await platform.invokeMethod('getOverlayMetadata', <String, dynamic>{
|
||||||
'path': path,
|
'path': path,
|
||||||
|
@ -52,4 +52,4 @@ class ImageFetcher {
|
||||||
}
|
}
|
||||||
return Map();
|
return Map();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ class Thumbnail extends StatefulWidget {
|
||||||
final double extent;
|
final double extent;
|
||||||
final double devicePixelRatio;
|
final double devicePixelRatio;
|
||||||
|
|
||||||
Thumbnail({
|
const Thumbnail({
|
||||||
Key key,
|
Key key,
|
||||||
@required this.entry,
|
@required this.entry,
|
||||||
@required this.extent,
|
@required this.extent,
|
||||||
|
|
|
@ -14,13 +14,12 @@ class ThumbnailCollection extends StatelessWidget {
|
||||||
final Map<DateTime, List<Map>> sections;
|
final Map<DateTime, List<Map>> sections;
|
||||||
final ScrollController scrollController = ScrollController();
|
final ScrollController scrollController = ScrollController();
|
||||||
|
|
||||||
ThumbnailCollection(this.entries) : sections = groupBy(entries, ImageEntry.getDayTaken);
|
ThumbnailCollection({Key key, this.entries})
|
||||||
|
: sections = groupBy(entries, ImageEntry.getDayTaken),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var columnCount = 4;
|
|
||||||
var mediaQuery = MediaQuery.of(context);
|
|
||||||
|
|
||||||
return DraggableScrollbar.arrows(
|
return DraggableScrollbar.arrows(
|
||||||
labelTextBuilder: (double offset) => Text(
|
labelTextBuilder: (double offset) => Text(
|
||||||
"${offset ~/ 1}",
|
"${offset ~/ 1}",
|
||||||
|
@ -34,34 +33,59 @@ class ThumbnailCollection extends StatelessWidget {
|
||||||
title: Text('Aves - All'),
|
title: Text('Aves - All'),
|
||||||
floating: true,
|
floating: true,
|
||||||
),
|
),
|
||||||
...sections.keys.map((sectionKey) => SliverStickyHeader(
|
...sections.keys.map((sectionKey) => SectionSliver(
|
||||||
header: DaySectionHeader(sectionKey),
|
entries: entries,
|
||||||
sliver: SliverGrid(
|
sections: sections,
|
||||||
delegate: SliverChildBuilderDelegate(
|
sectionKey: sectionKey,
|
||||||
(context, index) {
|
)),
|
||||||
var sectionEntries = sections[sectionKey];
|
|
||||||
if (index >= sectionEntries.length) return null;
|
|
||||||
var entry = sectionEntries[index];
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: () => _showFullscreen(context, entry),
|
|
||||||
child: Thumbnail(
|
|
||||||
entry: entry,
|
|
||||||
extent: mediaQuery.size.width / columnCount,
|
|
||||||
devicePixelRatio: mediaQuery.devicePixelRatio,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
childCount: sections[sectionKey].length,
|
|
||||||
),
|
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
|
||||||
crossAxisCount: columnCount,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
))
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SectionSliver extends StatelessWidget {
|
||||||
|
final List<Map> entries;
|
||||||
|
final Map<DateTime, List<Map>> sections;
|
||||||
|
final DateTime sectionKey;
|
||||||
|
|
||||||
|
const SectionSliver({
|
||||||
|
Key key,
|
||||||
|
this.entries,
|
||||||
|
this.sections,
|
||||||
|
this.sectionKey,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var columnCount = 4;
|
||||||
|
var mediaQuery = MediaQuery.of(context);
|
||||||
|
|
||||||
|
return SliverStickyHeader(
|
||||||
|
header: DaySectionHeader(date: sectionKey),
|
||||||
|
sliver: SliverGrid(
|
||||||
|
delegate: SliverChildBuilderDelegate(
|
||||||
|
(context, index) {
|
||||||
|
var sectionEntries = sections[sectionKey];
|
||||||
|
if (index >= sectionEntries.length) return null;
|
||||||
|
var entry = sectionEntries[index];
|
||||||
|
return GestureDetector(
|
||||||
|
onTap: () => _showFullscreen(context, entry),
|
||||||
|
child: Thumbnail(
|
||||||
|
entry: entry,
|
||||||
|
extent: mediaQuery.size.width / columnCount,
|
||||||
|
devicePixelRatio: mediaQuery.devicePixelRatio,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
childCount: sections[sectionKey].length,
|
||||||
|
),
|
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
|
crossAxisCount: columnCount,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future _showFullscreen(BuildContext context, Map entry) {
|
Future _showFullscreen(BuildContext context, Map entry) {
|
||||||
return Navigator.push(
|
return Navigator.push(
|
||||||
|
@ -79,6 +103,10 @@ class ThumbnailCollection extends StatelessWidget {
|
||||||
class DaySectionHeader extends StatelessWidget {
|
class DaySectionHeader extends StatelessWidget {
|
||||||
final String text;
|
final String text;
|
||||||
|
|
||||||
|
DaySectionHeader({Key key, DateTime date})
|
||||||
|
: text = formatDate(date),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
static DateFormat md = DateFormat.MMMMd();
|
static DateFormat md = DateFormat.MMMMd();
|
||||||
static DateFormat ymd = DateFormat.yMMMMd();
|
static DateFormat ymd = DateFormat.yMMMMd();
|
||||||
|
|
||||||
|
@ -88,25 +116,23 @@ class DaySectionHeader extends StatelessWidget {
|
||||||
return ymd.format(date);
|
return ymd.format(date);
|
||||||
}
|
}
|
||||||
|
|
||||||
DaySectionHeader(DateTime date) : text = formatDate(date);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SectionHeader(text);
|
return SectionHeader(text: text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SectionHeader extends StatelessWidget {
|
class SectionHeader extends StatelessWidget {
|
||||||
final String primaryText;
|
final String text;
|
||||||
|
|
||||||
SectionHeader(this.primaryText);
|
const SectionHeader({Key key, this.text}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
padding: EdgeInsets.all(16),
|
padding: EdgeInsets.all(16),
|
||||||
child: OutlinedText(
|
child: OutlinedText(
|
||||||
primaryText,
|
text,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.grey[200],
|
color: Colors.grey[200],
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
|
|
Loading…
Reference in a new issue