#132 fixed magnifier controller widget update

This commit is contained in:
Thibault Deckers 2021-12-01 11:33:51 +09:00
parent 8c535dcb9c
commit a1b8d313e8
4 changed files with 67 additions and 55 deletions

View file

@ -31,9 +31,16 @@ mixin MagnifierControllerDelegate on State<MagnifierCore> {
final List<StreamSubscription> _subscriptions = [];
void startListeners() {
_subscriptions.add(controller.stateStream.listen(_onMagnifierStateChange));
_subscriptions.add(controller.scaleStateChangeStream.listen(_onScaleStateChange));
void registerDelegate(MagnifierCore widget) {
_subscriptions.add(widget.controller.stateStream.listen(_onMagnifierStateChange));
_subscriptions.add(widget.controller.scaleStateChangeStream.listen(_onScaleStateChange));
}
void unregisterDelegate(MagnifierCore oldWidget) {
_animateScale = null;
_subscriptions
..forEach((sub) => sub.cancel())
..clear();
}
void _onScaleStateChange(ScaleStateChange scaleStateChange) {
@ -181,14 +188,6 @@ mixin MagnifierControllerDelegate on State<MagnifierCore> {
return Offset(finalX, finalY);
}
@override
void dispose() {
_animateScale = null;
_subscriptions.forEach((sub) => sub.cancel());
_subscriptions.clear();
super.dispose();
}
}
/// Simple class to store a min and a max value

View file

@ -12,30 +12,25 @@ import 'package:flutter/widgets.dart';
/// Internal widget in which controls all animations lifecycle, core responses
/// to user gestures, updates to the controller state and mounts the entire Layout
class MagnifierCore extends StatefulWidget {
final MagnifierController controller;
final ScaleStateCycle scaleStateCycle;
final bool applyScale;
final double panInertia;
final MagnifierTapCallback? onTap;
final Widget child;
const MagnifierCore({
Key? key,
required this.child,
required this.onTap,
required this.controller,
required this.scaleStateCycle,
required this.applyScale,
this.panInertia = .2,
required this.onTap,
required this.child,
}) : super(key: key);
final Widget child;
final MagnifierController controller;
final ScaleStateCycle scaleStateCycle;
final MagnifierTapCallback? onTap;
final bool applyScale;
final double panInertia;
@override
State<StatefulWidget> createState() {
return _MagnifierCoreState();
}
State<StatefulWidget> createState() => _MagnifierCoreState();
}
class _MagnifierCoreState extends State<MagnifierCore> with TickerProviderStateMixin, MagnifierControllerDelegate, CornerHitDetector {
@ -52,6 +47,45 @@ class _MagnifierCoreState extends State<MagnifierCore> with TickerProviderStateM
ScaleBoundaries? cachedScaleBoundaries;
@override
void initState() {
super.initState();
_scaleAnimationController = AnimationController(vsync: this)
..addListener(handleScaleAnimation)
..addStatusListener(onAnimationStatus);
_positionAnimationController = AnimationController(vsync: this)..addListener(handlePositionAnimate);
_registerWidget(widget);
}
@override
void didUpdateWidget(covariant MagnifierCore oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.controller != widget.controller) {
_unregisterWidget(oldWidget);
_registerWidget(widget);
}
}
@override
void dispose() {
_unregisterWidget(widget);
_scaleAnimationController.dispose();
_positionAnimationController.dispose();
super.dispose();
}
void _registerWidget(MagnifierCore widget) {
registerDelegate(widget);
cachedScaleBoundaries = widget.controller.scaleBoundaries;
setScaleStateUpdateAnimation(animateOnScaleStateUpdate);
}
void _unregisterWidget(MagnifierCore oldWidget) {
unregisterDelegate(oldWidget);
cachedScaleBoundaries = null;
}
void handleScaleAnimation() {
setScale(_scaleAnimation.value, ChangeSource.animation);
}
@ -202,33 +236,11 @@ class _MagnifierCoreState extends State<MagnifierCore> with TickerProviderStateM
}
}
@override
void initState() {
super.initState();
_scaleAnimationController = AnimationController(vsync: this)..addListener(handleScaleAnimation);
_scaleAnimationController.addStatusListener(onAnimationStatus);
_positionAnimationController = AnimationController(vsync: this)..addListener(handlePositionAnimate);
startListeners();
setScaleStateUpdateAnimation(animateOnScaleStateUpdate);
cachedScaleBoundaries = widget.controller.scaleBoundaries;
}
void animateOnScaleStateUpdate(double? prevScale, double? nextScale, Offset nextPosition) {
animateScale(prevScale, nextScale);
animatePosition(controller.position, nextPosition);
}
@override
void dispose() {
_scaleAnimationController.removeStatusListener(onAnimationStatus);
_scaleAnimationController.dispose();
_positionAnimationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
// Check if we need a recalc on the scale

View file

@ -66,8 +66,8 @@ class Magnifier extends StatelessWidget {
return MagnifierCore(
controller: controller,
scaleStateCycle: scaleStateCycle,
onTap: onTap,
applyScale: applyScale,
onTap: onTap,
child: child,
);
},

View file

@ -62,7 +62,7 @@ class _EntryPageViewState extends State<EntryPageView> {
@override
void initState() {
super.initState();
_registerWidget();
_registerWidget(widget);
}
@override
@ -70,19 +70,20 @@ class _EntryPageViewState extends State<EntryPageView> {
super.didUpdateWidget(oldWidget);
if (oldWidget.pageEntry != widget.pageEntry) {
_unregisterWidget();
_registerWidget();
_unregisterWidget(oldWidget);
_registerWidget(widget);
}
}
@override
void dispose() {
_unregisterWidget();
_unregisterWidget(widget);
widget.onDisposed?.call();
super.dispose();
}
void _registerWidget() {
void _registerWidget(EntryPageView widget) {
final entry = widget.pageEntry;
_viewStateNotifier = context.read<ViewStateConductor>().getOrCreateController(entry);
_magnifierController = MagnifierController();
_subscriptions.add(_magnifierController.stateStream.listen(_onViewStateChanged));
@ -94,7 +95,7 @@ class _EntryPageViewState extends State<EntryPageView> {
}
}
void _unregisterWidget() {
void _unregisterWidget(EntryPageView oldWidget) {
_videoCoverStream?.removeListener(_videoCoverStreamListener);
_videoCoverStream = null;
_videoCoverInfoNotifier.value = null;