fixed tiled view contained scale state not kept on orientation change

This commit is contained in:
Thibault Deckers 2020-11-17 15:47:57 +09:00
parent 0f773563f4
commit 613fe45fc2
2 changed files with 15 additions and 1 deletions

View file

@ -39,6 +39,7 @@ class ImageView extends StatefulWidget {
class _ImageViewState extends State<ImageView> { class _ImageViewState extends State<ImageView> {
final PhotoViewController _photoViewController = PhotoViewController(); final PhotoViewController _photoViewController = PhotoViewController();
final PhotoViewScaleStateController _photoViewScaleStateController = PhotoViewScaleStateController();
final ValueNotifier<ViewState> _viewStateNotifier = ValueNotifier<ViewState>(ViewState.zero); final ValueNotifier<ViewState> _viewStateNotifier = ValueNotifier<ViewState>(ViewState.zero);
StreamSubscription<PhotoViewControllerValue> _subscription; StreamSubscription<PhotoViewControllerValue> _subscription;
Size _photoViewChildSize; Size _photoViewChildSize;
@ -164,6 +165,15 @@ class _ImageViewState extends State<ImageView> {
child: Selector<MediaQueryData, Size>( child: Selector<MediaQueryData, Size>(
selector: (context, mq) => mq.size, selector: (context, mq) => mq.size,
builder: (context, mqSize, child) { builder: (context, mqSize, child) {
// When the scale state is cycled to be in its `initial` state (i.e. `contained`), and the device is rotated,
// `PhotoView` keeps the scale state as `contained`, but the controller does not update or notify the new scale value.
// We cannot use `scaleStateChangedCallback` as a workaround, because the scale state is updated before animating the scale change,
// so we keep receiving scale updates after the scale state update.
// Instead we check the scale state here when the constraints change, so we can reset the obsolete scale value.
if (_photoViewScaleStateController.scaleState == PhotoViewScaleState.initial) {
final value = PhotoViewControllerValue(position: Offset.zero, scale: 0, rotation: 0, rotationFocusPoint: null);
WidgetsBinding.instance.addPostFrameCallback((_) => _onViewChanged(value));
}
return TiledImageView( return TiledImageView(
entry: entry, entry: entry,
viewportSize: mqSize, viewportSize: mqSize,
@ -176,6 +186,7 @@ class _ImageViewState extends State<ImageView> {
childSize: entry.displaySize, childSize: entry.displaySize,
backgroundDecoration: backgroundDecoration, backgroundDecoration: backgroundDecoration,
controller: _photoViewController, controller: _photoViewController,
scaleStateController: _photoViewScaleStateController,
maxScale: maxScale, maxScale: maxScale,
minScale: PhotoViewComputedScale.contained, minScale: PhotoViewComputedScale.contained,
initialScale: PhotoViewComputedScale.contained, initialScale: PhotoViewComputedScale.contained,

View file

@ -56,7 +56,10 @@ class MinimapPainter extends CustomPainter {
@required this.viewScale, @required this.viewScale,
this.minimapBorderColor = Colors.white, this.minimapBorderColor = Colors.white,
this.viewportBorderColor = Colors.white, this.viewportBorderColor = Colors.white,
}); }) : assert(viewportSize != null),
assert(entrySize != null),
assert(viewCenterOffset != null),
assert(viewScale != null);
@override @override
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) {