info: keep alive info page (by metadata sliver) but only fetch metadata when necessary
This commit is contained in:
parent
4d914d9211
commit
77be0b6189
3 changed files with 53 additions and 7 deletions
|
@ -299,6 +299,7 @@ class FullscreenVerticalPageView extends StatefulWidget {
|
||||||
class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView> {
|
class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView> {
|
||||||
bool _isInitialScale = true;
|
bool _isInitialScale = true;
|
||||||
ValueNotifier<Color> _backgroundColorNotifier = ValueNotifier(Colors.black);
|
ValueNotifier<Color> _backgroundColorNotifier = ValueNotifier(Colors.black);
|
||||||
|
ValueNotifier<bool> _infoPageVisibleNotifier = ValueNotifier(false);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
@ -343,8 +344,12 @@ class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView>
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection: Axis.vertical,
|
||||||
controller: widget.verticalPager,
|
controller: widget.verticalPager,
|
||||||
physics: _isInitialScale ? const PageScrollPhysics() : const NeverScrollableScrollPhysics(),
|
physics: _isInitialScale ? const PageScrollPhysics() : const NeverScrollableScrollPhysics(),
|
||||||
onPageChanged: widget.onVerticalPageChanged,
|
onPageChanged: (page) {
|
||||||
|
widget.onVerticalPageChanged(page);
|
||||||
|
_infoPageVisibleNotifier.value = page == FullscreenBodyState.infoPage;
|
||||||
|
},
|
||||||
children: [
|
children: [
|
||||||
|
// fake page for opacity transition between collection and fullscreen views
|
||||||
const SizedBox(),
|
const SizedBox(),
|
||||||
ImagePage(
|
ImagePage(
|
||||||
collection: widget.collection,
|
collection: widget.collection,
|
||||||
|
@ -359,7 +364,11 @@ class _FullscreenVerticalPageViewState extends State<FullscreenVerticalPageView>
|
||||||
if (notification is BackUpNotification) widget.onImagePageRequested();
|
if (notification is BackUpNotification) widget.onImagePageRequested();
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
child: InfoPage(collection: widget.collection, entry: widget.entry),
|
child: InfoPage(
|
||||||
|
collection: widget.collection,
|
||||||
|
entry: widget.entry,
|
||||||
|
visibleNotifier: _infoPageVisibleNotifier,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -14,11 +14,13 @@ import 'package:tuple/tuple.dart';
|
||||||
class InfoPage extends StatefulWidget {
|
class InfoPage extends StatefulWidget {
|
||||||
final ImageCollection collection;
|
final ImageCollection collection;
|
||||||
final ImageEntry entry;
|
final ImageEntry entry;
|
||||||
|
final ValueNotifier<bool> visibleNotifier;
|
||||||
|
|
||||||
const InfoPage({
|
const InfoPage({
|
||||||
Key key,
|
Key key,
|
||||||
@required this.collection,
|
@required this.collection,
|
||||||
@required this.entry,
|
@required this.entry,
|
||||||
|
this.visibleNotifier,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -97,7 +99,11 @@ class InfoPageState extends State<InfoPage> {
|
||||||
),
|
),
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: horizontalPadding,
|
padding: horizontalPadding,
|
||||||
sliver: MetadataSectionSliver(entry: entry, columnCount: split ? 2 : 1),
|
sliver: MetadataSectionSliver(
|
||||||
|
entry: entry,
|
||||||
|
columnCount: split ? 2 : 1,
|
||||||
|
visibleNotifier: widget.visibleNotifier,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
SliverPadding(
|
SliverPadding(
|
||||||
padding: EdgeInsets.only(bottom: 8 + mqViewInsetsBottom),
|
padding: EdgeInsets.only(bottom: 8 + mqViewInsetsBottom),
|
||||||
|
|
|
@ -10,34 +10,56 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||||||
class MetadataSectionSliver extends StatefulWidget {
|
class MetadataSectionSliver extends StatefulWidget {
|
||||||
final ImageEntry entry;
|
final ImageEntry entry;
|
||||||
final int columnCount;
|
final int columnCount;
|
||||||
|
final ValueNotifier<bool> visibleNotifier;
|
||||||
|
|
||||||
const MetadataSectionSliver({
|
const MetadataSectionSliver({
|
||||||
@required this.entry,
|
@required this.entry,
|
||||||
@required this.columnCount,
|
@required this.columnCount,
|
||||||
|
this.visibleNotifier,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _MetadataSectionSliverState();
|
State<StatefulWidget> createState() => _MetadataSectionSliverState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MetadataSectionSliverState extends State<MetadataSectionSliver> {
|
class _MetadataSectionSliverState extends State<MetadataSectionSliver> with AutomaticKeepAliveClientMixin {
|
||||||
Map _metadata;
|
Map _metadata;
|
||||||
|
String _loadedMetadataUri;
|
||||||
|
|
||||||
|
bool get isVisible => widget.visibleNotifier.value;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
_registerWidget(widget);
|
||||||
_getMetadata();
|
_getMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didUpdateWidget(MetadataSectionSliver oldWidget) {
|
void didUpdateWidget(MetadataSectionSliver oldWidget) {
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
|
_unregisterWidget(oldWidget);
|
||||||
|
_registerWidget(widget);
|
||||||
_getMetadata();
|
_getMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_unregisterWidget(widget);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _registerWidget(MetadataSectionSliver widget) {
|
||||||
|
widget.visibleNotifier.addListener(_getMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _unregisterWidget(MetadataSectionSliver widget) {
|
||||||
|
widget.visibleNotifier.removeListener(_getMetadata);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
debugPrint('$runtimeType build');
|
super.build(context);
|
||||||
final directoryNames = (_metadata?.keys?.toList() ?? [])..sort();
|
final directoryNames = (_metadata?.keys?.toList() ?? [])..sort();
|
||||||
return SliverStaggeredGrid.countBuilder(
|
return SliverStaggeredGrid.countBuilder(
|
||||||
crossAxisCount: widget.columnCount,
|
crossAxisCount: widget.columnCount,
|
||||||
|
@ -57,10 +79,19 @@ class _MetadataSectionSliverState extends State<MetadataSectionSliver> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _getMetadata() async {
|
Future<void> _getMetadata() async {
|
||||||
debugPrint('$runtimeType _getMetadata');
|
if (_loadedMetadataUri == widget.entry.uri) return;
|
||||||
_metadata = await MetadataService.getAllMetadata(widget.entry);
|
if (isVisible) {
|
||||||
|
_metadata = await MetadataService.getAllMetadata(widget.entry);
|
||||||
|
_loadedMetadataUri = widget.entry.uri;
|
||||||
|
} else {
|
||||||
|
_metadata = null;
|
||||||
|
_loadedMetadataUri = null;
|
||||||
|
}
|
||||||
if (mounted) setState(() {});
|
if (mounted) setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get wantKeepAlive => true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _Directory extends StatelessWidget {
|
class _Directory extends StatelessWidget {
|
||||||
|
|
Loading…
Reference in a new issue