Toggle navigation
Toggle navigation
This project
Loading...
Sign in
flutter_package
/
fluttertpc_get
Go to a project
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Jonny Borges
2021-07-11 13:50:56 -0300
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
3156b6f651dc1f4f8817cd9a752e994352c56033
3156b6f6
1 parent
e7867e78
add transition mixin
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
887 additions
and
550 deletions
lib/get_navigation/src/extension_navigation.dart
lib/get_navigation/src/root/get_cupertino_app.dart
lib/get_navigation/src/root/get_material_app.dart
lib/get_navigation/src/routes/default_route.dart
lib/get_navigation/src/routes/get_page_route.dart
lib/get_navigation/src/routes/get_route.dart
lib/get_navigation/src/routes/get_transition_mixin.dart
lib/get_navigation/src/routes/route_middleware.dart
lib/get_navigation/src/extension_navigation.dart
View file @
3156b6f
...
...
@@ -494,6 +494,7 @@ extension GetNavigation on GetInterface {
Bindings
?
binding
,
bool
preventDuplicates
=
true
,
bool
?
popGesture
,
double
gestureWidth
=
20
,
})
{
var
routeName
=
"/
${page.runtimeType.toString()}
"
;
if
(
preventDuplicates
&&
routeName
==
currentRoute
)
{
...
...
@@ -504,6 +505,7 @@ extension GetNavigation on GetInterface {
opaque:
opaque
??
true
,
page:
_resolve
(
page
,
'to'
),
routeName:
routeName
,
gestureWidth:
gestureWidth
,
settings:
RouteSettings
(
// name: forceRouteName ? '${a.runtimeType}' : '',
arguments:
arguments
,
...
...
@@ -862,6 +864,7 @@ you can only use widgets and widget functions here''';
bool
fullscreenDialog
=
false
,
bool
preventDuplicates
=
true
,
Duration
?
duration
,
double
gestureWidth
=
20
,
})
{
var
routeName
=
"/
${page.runtimeType.toString()}
"
;
if
(
preventDuplicates
&&
routeName
==
currentRoute
)
{
...
...
@@ -869,6 +872,7 @@ you can only use widgets and widget functions here''';
}
return
global
(
id
).
currentState
?.
pushReplacement
(
GetPageRoute
(
opaque:
opaque
,
gestureWidth:
gestureWidth
,
page:
_resolve
(
page
,
'off'
),
binding:
binding
,
settings:
RouteSettings
(
arguments:
arguments
),
...
...
@@ -923,6 +927,7 @@ you can only use widgets and widget functions here''';
Transition
?
transition
,
Curve
?
curve
,
Duration
?
duration
,
double
gestureWidth
=
20
,
})
{
var
routeName
=
"/
${page.runtimeType.toString()}
"
;
...
...
@@ -932,6 +937,7 @@ you can only use widgets and widget functions here''';
popGesture:
popGesture
??
defaultPopGesture
,
page:
_resolve
(
page
,
'offAll'
),
binding:
binding
,
gestureWidth:
gestureWidth
,
settings:
RouteSettings
(
arguments:
arguments
),
fullscreenDialog:
fullscreenDialog
,
routeName:
routeName
,
...
...
@@ -1054,8 +1060,8 @@ you can only use widgets and widget functions here''';
return
_key
;
}
/// Casts the stored router delegate to a desired type
/// Casts the stored router delegate to a desired type
TDelegate
?
delegate
<
TDelegate
extends
RouterDelegate
<
TPage
>,
TPage
>()
=>
_routerDelegate
as
TDelegate
?;
...
...
lib/get_navigation/src/root/get_cupertino_app.dart
View file @
3156b6f
...
...
@@ -174,11 +174,17 @@ class GetCupertinoApp extends StatelessWidget {
super
(
key:
key
);
Route
<
dynamic
>
generator
(
RouteSettings
settings
)
{
return
PageRedirect
(
settings
,
unknownRoute
).
page
();
return
PageRedirect
(
settings
:
settings
,
unknownRoute:
unknownRoute
).
page
();
}
List
<
Route
<
dynamic
>>
initialRoutesGenerate
(
String
name
)
=>
[
PageRedirect
(
RouteSettings
(
name:
name
),
unknownRoute
).
page
()];
List
<
Route
<
dynamic
>>
initialRoutesGenerate
(
String
name
)
{
return
[
PageRedirect
(
settings:
RouteSettings
(
name:
name
),
unknownRoute:
unknownRoute
,
).
page
()
];
}
@override
Widget
build
(
BuildContext
context
)
=>
GetBuilder
<
GetMaterialController
>(
...
...
lib/get_navigation/src/root/get_material_app.dart
View file @
3156b6f
...
...
@@ -183,11 +183,18 @@ class GetMaterialApp extends StatelessWidget {
initialRoute
=
null
,
super
(
key:
key
);
Route
<
dynamic
>
generator
(
RouteSettings
settings
)
=>
PageRedirect
(
settings
,
unknownRoute
).
page
();
Route
<
dynamic
>
generator
(
RouteSettings
settings
)
{
return
PageRedirect
(
settings:
settings
,
unknownRoute:
unknownRoute
).
page
();
}
List
<
Route
<
dynamic
>>
initialRoutesGenerate
(
String
name
)
=>
[
PageRedirect
(
RouteSettings
(
name:
name
),
unknownRoute
).
page
()];
List
<
Route
<
dynamic
>>
initialRoutesGenerate
(
String
name
)
{
return
[
PageRedirect
(
settings:
RouteSettings
(
name:
name
),
unknownRoute:
unknownRoute
,
).
page
()
];
}
@override
Widget
build
(
BuildContext
context
)
=>
GetBuilder
<
GetMaterialController
>(
...
...
lib/get_navigation/src/routes/default_route.dart
View file @
3156b6f
import
'dart:math'
;
import
'dart:ui'
show
lerpDouble
;
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/gestures.dart'
;
import
'package:flutter/material.dart'
;
import
'../../../get_core/get_core.dart'
;
import
'../../../get_instance/get_instance.dart'
;
import
'../../get_navigation.dart'
;
import
'../../../get.dart'
;
import
'custom_transition.dart'
;
import
'default_transitions.dart'
;
import
'get_transition_mixin.dart'
;
import
'route_middleware.dart'
;
import
'transitions_type.dart'
;
class
GetPageRoute
<
T
>
extends
PageRoute
<
T
>
{
class
GetPageRoute
<
T
>
extends
PageRoute
<
T
>
with
GetPageRouteTransitionMixin
<
T
>
{
/// Creates a page route for use in an iOS designed app.
///
/// The [builder], [maintainState], and [fullscreenDialog] arguments must not
/// be null.
GetPageRoute
({
RouteSettings
?
settings
,
this
.
transitionDuration
=
const
Duration
(
milliseconds:
300
),
this
.
opaque
=
true
,
this
.
parameter
,
this
.
gestureWidth
=
20.0
,
this
.
curve
,
this
.
alignment
,
this
.
transition
,
...
...
@@ -27,6 +28,7 @@ class GetPageRoute<T> extends PageRoute<T> {
this
.
bindings
,
this
.
routeName
,
this
.
page
,
this
.
title
,
this
.
barrierLabel
,
this
.
maintainState
=
true
,
bool
fullscreenDialog
=
false
,
...
...
@@ -36,35 +38,23 @@ class GetPageRoute<T> extends PageRoute<T> {
@override
final
Duration
transitionDuration
;
final
GetPageBuilder
?
page
;
final
String
?
routeName
;
final
String
reference
;
final
CustomTransition
?
customTransition
;
final
Bindings
?
binding
;
final
Map
<
String
,
String
>?
parameter
;
final
List
<
Bindings
>?
bindings
;
@override
final
bool
opaque
;
final
bool
?
popGesture
;
@override
final
bool
barrierDismissible
;
final
Transition
?
transition
;
final
Curve
?
curve
;
final
Alignment
?
alignment
;
final
List
<
GetMiddleware
>?
middlewares
;
@override
...
...
@@ -77,308 +67,6 @@ class GetPageRoute<T> extends PageRoute<T> {
final
bool
maintainState
;
@override
bool
canTransitionTo
(
TransitionRoute
<
dynamic
>
nextRoute
)
{
// Don't perform outgoing animation if the next route is a
// fullscreen dialog.
return
nextRoute
is
PageRoute
&&
!
nextRoute
.
fullscreenDialog
;
}
static
bool
_isPopGestureEnabled
<
T
>(
PageRoute
<
T
>
route
)
{
// ignore: lines_longer_than_80_chars
if
(
route
.
isFirst
||
route
.
willHandlePopInternally
||
route
.
hasScopedWillPopCallback
||
route
.
fullscreenDialog
||
route
.
animation
!.
status
!=
AnimationStatus
.
completed
||
route
.
secondaryAnimation
!.
status
!=
AnimationStatus
.
dismissed
||
isPopGestureInProgress
(
route
))
return
false
;
return
true
;
}
static
_CupertinoBackGestureController
<
T
>
_startPopGesture
<
T
>(
PageRoute
<
T
>
route
)
{
assert
(
_isPopGestureEnabled
(
route
));
return
_CupertinoBackGestureController
<
T
>(
navigator:
route
.
navigator
!,
controller:
route
.
controller
!,
);
}
@override
Widget
buildPage
(
BuildContext
?
context
,
Animation
<
double
>?
animation
,
Animation
<
double
>?
secondaryAnimation
,
)
{
// Get.reference = settings.name ?? routeName;
Get
.
reference
=
reference
;
final
middlewareRunner
=
MiddlewareRunner
(
middlewares
);
final
bindingsToBind
=
middlewareRunner
.
runOnBindingsStart
(
bindings
);
binding
?.
dependencies
();
if
(
bindingsToBind
!=
null
)
{
for
(
final
binding
in
bindingsToBind
)
{
binding
.
dependencies
();
}
}
final
pageToBuild
=
middlewareRunner
.
runOnPageBuildStart
(
page
)!;
return
middlewareRunner
.
runOnPageBuilt
(
pageToBuild
());
}
static
bool
isPopGestureInProgress
(
PageRoute
<
dynamic
>
route
)
{
return
route
.
navigator
!.
userGestureInProgress
;
}
bool
get
popGestureInProgress
=>
isPopGestureInProgress
(
this
);
@override
Widget
buildTransitions
(
BuildContext
context
,
Animation
<
double
>
animation
,
Animation
<
double
>
secondaryAnimation
,
Widget
child
)
{
final
finalCurve
=
curve
??
Get
.
defaultTransitionCurve
;
final
hasCurve
=
curve
!=
null
;
if
(
fullscreenDialog
&&
transition
==
null
)
{
/// by default, if no curve is defined, use Cupertino transition in the
/// default way (no linearTransition)... otherwise take the curve passed.
return
CupertinoFullscreenDialogTransition
(
primaryRouteAnimation:
hasCurve
?
CurvedAnimation
(
parent:
animation
,
curve:
finalCurve
)
:
animation
,
secondaryRouteAnimation:
secondaryAnimation
,
child:
child
,
linearTransition:
hasCurve
);
}
if
(
customTransition
!=
null
)
{
return
customTransition
!.
buildTransition
(
context
,
finalCurve
,
alignment
,
animation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
,
);
}
/// Apply the curve by default...
final
iosAnimation
=
animation
;
animation
=
CurvedAnimation
(
parent:
animation
,
curve:
finalCurve
);
switch
(
transition
??
Get
.
defaultTransition
)
{
case
Transition
.
leftToRight
:
return
SlideLeftTransition
().
buildTransitions
(
context
,
curve
,
alignment
,
animation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
);
case
Transition
.
downToUp
:
return
SlideDownTransition
().
buildTransitions
(
context
,
curve
,
alignment
,
animation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
);
case
Transition
.
upToDown
:
return
SlideTopTransition
().
buildTransitions
(
context
,
curve
,
alignment
,
animation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
);
case
Transition
.
noTransition
:
return
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
;
case
Transition
.
rightToLeft
:
return
SlideRightTransition
().
buildTransitions
(
context
,
curve
,
alignment
,
animation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
);
case
Transition
.
zoom
:
return
ZoomInTransition
().
buildTransitions
(
context
,
curve
,
alignment
,
animation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
);
case
Transition
.
fadeIn
:
return
FadeInTransition
().
buildTransitions
(
context
,
curve
,
alignment
,
animation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
);
case
Transition
.
rightToLeftWithFade
:
return
RightToLeftFadeTransition
().
buildTransitions
(
context
,
curve
,
alignment
,
animation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
);
case
Transition
.
leftToRightWithFade
:
return
LeftToRightFadeTransition
().
buildTransitions
(
context
,
curve
,
alignment
,
animation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
);
case
Transition
.
cupertino
:
return
CupertinoPageTransitionsBuilder
().
buildTransitions
(
this
,
context
,
iosAnimation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
);
case
Transition
.
size
:
return
SizeTransitions
().
buildTransitions
(
context
,
curve
!,
alignment
,
animation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
);
case
Transition
.
fade
:
return
FadeUpwardsPageTransitionsBuilder
().
buildTransitions
(
this
,
context
,
animation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
);
case
Transition
.
topLevel
:
return
ZoomPageTransitionsBuilder
().
buildTransitions
(
this
,
context
,
animation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
);
case
Transition
.
native
:
return
PageTransitionsTheme
().
buildTransitions
(
this
,
context
,
iosAnimation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
);
default
:
if
(
Get
.
customTransition
!=
null
)
{
return
Get
.
customTransition
!.
buildTransition
(
context
,
curve
,
alignment
,
animation
,
secondaryAnimation
,
child
);
}
return
PageTransitionsTheme
().
buildTransitions
(
this
,
context
,
iosAnimation
,
secondaryAnimation
,
popGesture
??
Get
.
defaultPopGesture
?
_CupertinoBackGestureDetector
<
T
>(
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
this
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
this
),
child:
child
)
:
child
);
}
}
@override
void
dispose
()
{
super
.
dispose
();
if
(
Get
.
smartManagement
!=
SmartManagement
.
onlyBuilder
)
{
...
...
@@ -396,220 +84,30 @@ class GetPageRoute<T> extends PageRoute<T> {
final
middlewareRunner
=
MiddlewareRunner
(
middlewares
);
middlewareRunner
.
runOnPageDispose
();
}
}
const
double
_kBackGestureWidth
=
20.0
;
const
double
_kMinFlingVelocity
=
1.0
;
const
int
_kMaxDroppedSwipePageForwardAnimationTime
=
800
;
// Milliseconds.
// The maximum time for a page to get reset to it's original position if the
// user releases a page mid swipe.
const
int
_kMaxPageBackAnimationTime
=
300
;
class
_CupertinoBackGestureDetector
<
T
>
extends
StatefulWidget
{
const
_CupertinoBackGestureDetector
({
Key
?
key
,
required
this
.
enabledCallback
,
required
this
.
onStartPopGesture
,
required
this
.
child
,
})
:
super
(
key:
key
);
final
Widget
child
;
final
ValueGetter
<
bool
>
enabledCallback
;
final
ValueGetter
<
_CupertinoBackGestureController
<
T
>>
onStartPopGesture
;
@override
_CupertinoBackGestureDetectorState
<
T
>
createState
()
=>
_CupertinoBackGestureDetectorState
<
T
>();
}
class
_CupertinoBackGestureDetectorState
<
T
>
extends
State
<
_CupertinoBackGestureDetector
<
T
>>
{
_CupertinoBackGestureController
<
T
>?
_backGestureController
;
Widget
buildContent
(
BuildContext
context
)
{
Get
.
reference
=
reference
;
final
middlewareRunner
=
MiddlewareRunner
(
middlewares
);
final
bindingsToBind
=
middlewareRunner
.
runOnBindingsStart
(
bindings
);
late
HorizontalDragGestureRecognizer
_recognizer
;
binding
?.
dependencies
();
if
(
bindingsToBind
!=
null
)
{
for
(
final
binding
in
bindingsToBind
)
{
binding
.
dependencies
();
}
}
@override
void
initState
()
{
super
.
initState
();
_recognizer
=
HorizontalDragGestureRecognizer
(
debugOwner:
this
)
..
onStart
=
_handleDragStart
..
onUpdate
=
_handleDragUpdate
..
onEnd
=
_handleDragEnd
..
onCancel
=
_handleDragCancel
;
final
pageToBuild
=
middlewareRunner
.
runOnPageBuildStart
(
page
)!;
return
middlewareRunner
.
runOnPageBuilt
(
pageToBuild
());
}
@override
void
dispose
()
{
_recognizer
.
dispose
();
super
.
dispose
();
}
void
_handleDragStart
(
DragStartDetails
details
)
{
assert
(
mounted
);
assert
(
_backGestureController
==
null
);
_backGestureController
=
widget
.
onStartPopGesture
();
}
void
_handleDragUpdate
(
DragUpdateDetails
details
)
{
assert
(
mounted
);
assert
(
_backGestureController
!=
null
);
_backGestureController
!.
dragUpdate
(
_convertToLogical
(
details
.
primaryDelta
!
/
context
.
size
!.
width
)!);
}
void
_handleDragEnd
(
DragEndDetails
details
)
{
assert
(
mounted
);
assert
(
_backGestureController
!=
null
);
_backGestureController
!.
dragEnd
(
_convertToLogical
(
details
.
velocity
.
pixelsPerSecond
.
dx
/
context
.
size
!.
width
)!);
_backGestureController
=
null
;
}
void
_handleDragCancel
()
{
assert
(
mounted
);
// This can be called even if start is not called, paired with
// the "down" event that we don't consider here.
_backGestureController
?.
dragEnd
(
0.0
);
_backGestureController
=
null
;
}
void
_handlePointerDown
(
PointerDownEvent
event
)
{
if
(
widget
.
enabledCallback
())
_recognizer
.
addPointer
(
event
);
}
double
?
_convertToLogical
(
double
value
)
{
switch
(
Directionality
.
of
(
context
))
{
case
TextDirection
.
rtl
:
return
-
value
;
case
TextDirection
.
ltr
:
return
value
;
default
:
return
value
;
}
}
final
String
?
title
;
@override
Widget
build
(
BuildContext
context
)
{
assert
(
debugCheckHasDirectionality
(
context
));
// For devices with notches, the drag area needs to be larger on the side
// that has the notch.
var
dragAreaWidth
=
Directionality
.
of
(
context
)
==
TextDirection
.
ltr
?
MediaQuery
.
of
(
context
).
padding
.
left
:
MediaQuery
.
of
(
context
).
padding
.
right
;
dragAreaWidth
=
max
(
dragAreaWidth
,
_kBackGestureWidth
);
return
Stack
(
fit:
StackFit
.
passthrough
,
children:
<
Widget
>[
widget
.
child
,
PositionedDirectional
(
start:
0.0
,
width:
dragAreaWidth
,
top:
0.0
,
bottom:
0.0
,
child:
Listener
(
onPointerDown:
_handlePointerDown
,
behavior:
HitTestBehavior
.
translucent
,
),
),
],
);
}
}
class
_CupertinoBackGestureController
<
T
>
{
/// Creates a controller for an iOS-style back gesture.
///
/// The [navigator] and [controller] arguments must not be null.
_CupertinoBackGestureController
({
required
this
.
navigator
,
required
this
.
controller
,
})
{
navigator
.
didStartUserGesture
();
}
final
AnimationController
controller
;
final
NavigatorState
navigator
;
/// The drag gesture has changed by [fractionalDelta]. The total range of the
/// drag should be 0.0 to 1.0.
void
dragUpdate
(
double
delta
)
{
controller
.
value
-=
delta
;
}
/// The drag gesture has ended with a horizontal motion of
/// [fractionalVelocity] as a fraction of screen width per second.
void
dragEnd
(
double
velocity
)
{
// Fling in the appropriate direction.
// AnimationController.fling is guaranteed to
// take at least one frame.
//
// This curve has been determined through rigorously eyeballing native iOS
// animations.
const
Curve
animationCurve
=
Curves
.
fastLinearToSlowEaseIn
;
bool
animateForward
;
// If the user releases the page before mid screen with sufficient velocity,
// or after mid screen, we should animate the page out. Otherwise, the page
// should be animated back in.
if
(
velocity
.
abs
()
>=
_kMinFlingVelocity
)
{
animateForward
=
velocity
<=
0
;
}
else
{
animateForward
=
controller
.
value
>
0.5
;
}
String
get
debugLabel
=>
'
${super.debugLabel}
(
${settings.name}
)'
;
if
(
animateForward
)
{
// The closer the panel is to dismissing, the shorter the animation is.
// We want to cap the animation time, but we want to use a linear curve
// to determine it.
final
droppedPageForwardAnimationTime
=
min
(
lerpDouble
(
_kMaxDroppedSwipePageForwardAnimationTime
,
0
,
controller
.
value
,
)!
.
floor
(),
_kMaxPageBackAnimationTime
,
);
controller
.
animateTo
(
1.0
,
duration:
Duration
(
milliseconds:
droppedPageForwardAnimationTime
),
curve:
animationCurve
);
}
else
{
// This route is destined to pop at this point. Reuse navigator's pop.
navigator
.
pop
();
// The popping may have finished inline if already at the target
// destination.
if
(
controller
.
isAnimating
)
{
// Otherwise, use a custom popping animation duration and curve.
final
droppedPageBackAnimationTime
=
lerpDouble
(
0
,
_kMaxDroppedSwipePageForwardAnimationTime
,
controller
.
value
,
)!
.
floor
();
controller
.
animateBack
(
0.0
,
duration:
Duration
(
milliseconds:
droppedPageBackAnimationTime
),
curve:
animationCurve
,
);
}
}
if
(
controller
.
isAnimating
)
{
// Keep the userGestureInProgress in true state so we don't change the
// curve of the page transition mid-flight since CupertinoPageTransition
// depends on userGestureInProgress.
late
AnimationStatusListener
animationStatusCallback
;
animationStatusCallback
=
(
status
)
{
navigator
.
didStopUserGesture
();
controller
.
removeStatusListener
(
animationStatusCallback
);
};
controller
.
addStatusListener
(
animationStatusCallback
);
}
else
{
navigator
.
didStopUserGesture
();
}
}
@override
final
double
gestureWidth
;
}
...
...
lib/get_navigation/src/routes/get_page_route.dart
0 → 100644
View file @
3156b6f
// import 'package:flutter/material.dart';
// import '../../../get.dart';
// import 'custom_transition.dart';
// import 'get_transition_mixin.dart';
// import 'route_middleware.dart';
// import 'transitions_type.dart';
// class GetPageRoute<T> extends PageRoute<T>
// with GetPageRouteTransitionMixin<T> {
// /// Creates a page route for use in an iOS designed app.
// ///
// /// The [builder], [maintainState], and [fullscreenDialog] arguments must not
// /// be null.
// GetPageRoute({
// RouteSettings? settings,
// this.transitionDuration = const Duration(milliseconds: 300),
// this.opaque = true,
// this.parameter,
// this.curve,
// this.alignment,
// this.transition,
// this.popGesture,
// this.customTransition,
// this.barrierDismissible = false,
// this.barrierColor,
// this.binding,
// this.bindings,
// this.routeName,
// this.page,
// this.title,
// this.barrierLabel,
// this.maintainState = true,
// bool fullscreenDialog = false,
// this.middlewares,
// }) : reference = "$routeName: ${settings?.hashCode ?? page.hashCode}",
// super(settings: settings, fullscreenDialog: fullscreenDialog);
// @override
// final Duration transitionDuration;
// final GetPageBuilder? page;
// final String? routeName;
// final String reference;
// final CustomTransition? customTransition;
// final Bindings? binding;
// final Map<String, String>? parameter;
// final List<Bindings>? bindings;
// @override
// final bool opaque;
// final bool? popGesture;
// @override
// final bool barrierDismissible;
// final Transition? transition;
// final Curve? curve;
// final Alignment? alignment;
// final List<GetMiddleware>? middlewares;
// @override
// final Color? barrierColor;
// @override
// final String? barrierLabel;
// @override
// final bool maintainState;
// @override
// void dispose() {
// super.dispose();
// if (Get.smartManagement != SmartManagement.onlyBuilder) {
// WidgetsBinding.instance!.addPostFrameCallback((_) {
// if (Get.reference != reference) {
// GetInstance().removeDependencyByRoute("$reference");
// }
// });
// }
// // if (Get.smartManagement != SmartManagement.onlyBuilder) {
// // GetInstance().removeDependencyByRoute("$reference");
// // }
// final middlewareRunner = MiddlewareRunner(middlewares);
// middlewareRunner.runOnPageDispose();
// }
// @override
// Widget buildContent(BuildContext context) {
// Get.reference = reference;
// final middlewareRunner = MiddlewareRunner(middlewares);
// final bindingsToBind = middlewareRunner.runOnBindingsStart(bindings);
// binding?.dependencies();
// if (bindingsToBind != null) {
// for (final binding in bindingsToBind) {
// binding.dependencies();
// }
// }
// final pageToBuild = middlewareRunner.runOnPageBuildStart(page)!;
// return middlewareRunner.runOnPageBuilt(pageToBuild());
// }
// @override
// final String? title;
// @override
// String get debugLabel => '${super.debugLabel}(${settings.name})';
// }
...
...
lib/get_navigation/src/routes/get_route.dart
View file @
3156b6f
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/widgets.dart'
;
...
...
@@ -36,6 +37,7 @@ class GetPage<T> extends Page<T> {
final
Alignment
?
alignment
;
final
bool
maintainState
;
final
bool
opaque
;
final
double
gestureWidth
;
final
Bindings
?
binding
;
final
List
<
Bindings
>
bindings
;
final
CustomTransition
?
customTransition
;
...
...
@@ -63,6 +65,7 @@ class GetPage<T> extends Page<T> {
required
this
.
name
,
required
this
.
page
,
this
.
title
,
this
.
gestureWidth
=
20
,
// RouteSettings settings,
this
.
maintainState
=
true
,
this
.
curve
=
Curves
.
linear
,
...
...
@@ -109,7 +112,7 @@ class GetPage<T> extends Page<T> {
return
PathDecoded
(
RegExp
(
'^
$stringPath
\$
'
),
keys
);
}
GetPage
copy
({
GetPage
<
T
>
copy
({
String
?
name
,
GetPageBuilder
?
page
,
bool
?
popGesture
,
...
...
@@ -130,6 +133,7 @@ class GetPage<T> extends Page<T> {
GetPage
?
unknownRoute
,
List
<
GetMiddleware
>?
middlewares
,
bool
?
preventDuplicates
,
double
?
gestureWidth
,
})
{
return
GetPage
(
preventDuplicates:
preventDuplicates
??
this
.
preventDuplicates
,
...
...
@@ -151,14 +155,17 @@ class GetPage<T> extends Page<T> {
children:
children
??
this
.
children
,
unknownRoute:
unknownRoute
??
this
.
unknownRoute
,
middlewares:
middlewares
??
this
.
middlewares
,
gestureWidth:
gestureWidth
??
this
.
gestureWidth
,
);
}
@override
Route
<
T
>
createRoute
(
BuildContext
context
)
{
// return GetPageRoute<T>(settings: this, page: page);
return
PageRedirect
(
this
,
unknownRoute
,
).
page
<
T
>();
route:
this
,
settings:
this
,
unknownRoute:
unknownRoute
,
).
getPageToRoute
<
T
>(
this
,
unknownRoute
);
}
}
...
...
lib/get_navigation/src/routes/get_transition_mixin.dart
0 → 100644
View file @
3156b6f
import
'dart:math'
;
import
'dart:ui'
;
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/gestures.dart'
;
import
'package:flutter/material.dart'
;
import
'../../../get.dart'
;
import
'default_transitions.dart'
;
import
'transitions_type.dart'
;
//const double _kBackGestureWidth = 20.0;
const
double
_kMinFlingVelocity
=
1.0
;
// Screen widths per second.
// An eyeballed value for the maximum time it takes
//for a page to animate forward
// if the user releases a page mid swipe.
const
int
_kMaxDroppedSwipePageForwardAnimationTime
=
800
;
// Milliseconds.
// The maximum time for a page to get reset to it's original position if the
// user releases a page mid swipe.
const
int
_kMaxPageBackAnimationTime
=
300
;
// Milliseconds.
mixin
GetPageRouteTransitionMixin
<
T
>
on
PageRoute
<
T
>
{
/// Builds the primary contents of the route.
@protected
Widget
buildContent
(
BuildContext
context
);
/// {@template flutter.cupertino.CupertinoRouteTransitionMixin.title}
/// A title string for this route.
///
/// Used to auto-populate [CupertinoNavigationBar] and
/// [CupertinoSliverNavigationBar]'s `middle`/`largeTitle` widgets when
/// one is not manually supplied.
/// {@endtemplate}
String
?
get
title
;
double
get
gestureWidth
;
ValueNotifier
<
String
?>?
_previousTitle
;
/// The title string of the previous [CupertinoPageRoute].
///
/// The [ValueListenable]'s value is readable after the route is installed
/// onto a [Navigator]. The [ValueListenable] will also notify its listeners
/// if the value changes (such as by replacing the previous route).
///
/// The [ValueListenable] itself will be null before the route is installed.
/// Its content value will be null if the previous route has no title or
/// is not a [CupertinoPageRoute].
///
/// See also:
///
/// * [ValueListenableBuilder], which can be used to listen and rebuild
/// widgets based on a ValueListenable.
ValueListenable
<
String
?>
get
previousTitle
{
assert
(
_previousTitle
!=
null
,
'''
Cannot read the previousTitle for a route that has not yet been installed'''
,
);
return
_previousTitle
!;
}
@override
void
didChangePrevious
(
Route
<
dynamic
>?
previousRoute
)
{
final
previousTitleString
=
previousRoute
is
CupertinoRouteTransitionMixin
?
previousRoute
.
title
:
null
;
if
(
_previousTitle
==
null
)
{
_previousTitle
=
ValueNotifier
<
String
?>(
previousTitleString
);
}
else
{
_previousTitle
!.
value
=
previousTitleString
;
}
super
.
didChangePrevious
(
previousRoute
);
}
@override
// A relatively rigorous eyeball estimation.
Duration
get
transitionDuration
=>
const
Duration
(
milliseconds:
400
);
@override
Color
?
get
barrierColor
=>
null
;
@override
String
?
get
barrierLabel
=>
null
;
@override
bool
canTransitionTo
(
TransitionRoute
<
dynamic
>
nextRoute
)
{
// Don't perform outgoing animation if the next route is a
// fullscreen dialog.
return
nextRoute
is
CupertinoRouteTransitionMixin
&&
!
nextRoute
.
fullscreenDialog
;
}
/// True if an iOS-style back swipe pop gesture is currently
/// underway for [route].
///
/// This just check the route's [NavigatorState.userGestureInProgress].
///
/// See also:
///
/// * [popGestureEnabled], which returns true if a user-triggered pop gesture
/// would be allowed.
static
bool
isPopGestureInProgress
(
PageRoute
<
dynamic
>
route
)
{
return
route
.
navigator
!.
userGestureInProgress
;
}
/// True if an iOS-style back swipe pop gesture is currently
/// underway for this route.
///
/// See also:
///
/// * [isPopGestureInProgress], which returns true if a Cupertino pop gesture
/// is currently underway for specific route.
/// * [popGestureEnabled], which returns true if a user-triggered pop gesture
/// would be allowed.
bool
get
popGestureInProgress
=>
isPopGestureInProgress
(
this
);
/// Whether a pop gesture can be started by the user.
///
/// Returns true if the user can edge-swipe to a previous route.
///
/// Returns false once [isPopGestureInProgress] is true, but
/// [isPopGestureInProgress] can only become true if [popGestureEnabled] was
/// true first.
///
/// This should only be used between frames, not during build.
bool
get
popGestureEnabled
=>
_isPopGestureEnabled
(
this
);
static
bool
_isPopGestureEnabled
<
T
>(
PageRoute
<
T
>
route
)
{
// If there's nothing to go back to, then obviously we don't support
// the back gesture.
if
(
route
.
isFirst
)
return
false
;
// If the route wouldn't actually pop if we popped it, then the gesture
// would be really confusing (or would skip internal routes),
//so disallow it.
if
(
route
.
willHandlePopInternally
)
return
false
;
// If attempts to dismiss this route might be vetoed such as in a page
// with forms, then do not allow the user to dismiss the route with a swipe.
if
(
route
.
hasScopedWillPopCallback
)
return
false
;
// Fullscreen dialogs aren't dismissible by back swipe.
if
(
route
.
fullscreenDialog
)
return
false
;
// If we're in an animation already, we cannot be manually swiped.
if
(
route
.
animation
!.
status
!=
AnimationStatus
.
completed
)
return
false
;
// If we're being popped into, we also cannot be swiped until the pop above
// it completes. This translates to our secondary animation being
// dismissed.
if
(
route
.
secondaryAnimation
!.
status
!=
AnimationStatus
.
dismissed
)
{
return
false
;
}
// If we're in a gesture already, we cannot start another.
if
(
isPopGestureInProgress
(
route
))
return
false
;
// Looks like a back gesture would be welcome!
return
true
;
}
@override
Widget
buildPage
(
BuildContext
context
,
Animation
<
double
>
animation
,
Animation
<
double
>
secondaryAnimation
)
{
final
child
=
buildContent
(
context
);
final
Widget
result
=
Semantics
(
scopesRoute:
true
,
explicitChildNodes:
true
,
child:
child
,
);
return
result
;
}
// Called by CupertinoBackGestureDetector when a pop ("back") drag start
// gesture is detected. The returned controller handles all of the subsequent
// drag events.
static
CupertinoBackGestureController
<
T
>
_startPopGesture
<
T
>(
PageRoute
<
T
>
route
)
{
assert
(
_isPopGestureEnabled
(
route
));
return
CupertinoBackGestureController
<
T
>(
navigator:
route
.
navigator
!,
controller:
route
.
controller
!,
// protected access
);
}
/// Returns a [CupertinoFullscreenDialogTransition] if [route] is a full
/// screen dialog, otherwise a [CupertinoPageTransition] is returned.
///
/// Used by [CupertinoPageRoute.buildTransitions].
///
/// This method can be applied to any [PageRoute], not just
/// [CupertinoPageRoute]. It's typically used to provide a Cupertino style
/// horizontal transition for material widgets when the target platform
/// is [TargetPlatform.iOS].
///
/// See also:
///
/// * [CupertinoPageTransitionsBuilder], which uses this method to define a
/// [PageTransitionsBuilder] for the [PageTransitionsTheme].
static
Widget
buildPageTransitions
<
T
>(
PageRoute
<
T
>
rawRoute
,
BuildContext
context
,
Animation
<
double
>
animation
,
Animation
<
double
>
secondaryAnimation
,
Widget
child
,
)
{
// Check if the route has an animation that's currently participating
// in a back swipe gesture.
//
// In the middle of a back gesture drag, let the transition be linear to
// match finger motions.
final
route
=
rawRoute
as
GetPageRoute
<
T
>;
final
linearTransition
=
isPopGestureInProgress
(
route
);
final
finalCurve
=
route
.
curve
??
Get
.
defaultTransitionCurve
;
final
hasCurve
=
route
.
curve
!=
null
;
if
(
route
.
fullscreenDialog
&&
route
.
transition
==
null
)
{
return
CupertinoFullscreenDialogTransition
(
primaryRouteAnimation:
hasCurve
?
CurvedAnimation
(
parent:
animation
,
curve:
finalCurve
)
:
animation
,
secondaryRouteAnimation:
secondaryAnimation
,
child:
child
,
linearTransition:
linearTransition
,
);
}
else
{
if
(
route
.
customTransition
!=
null
)
{
return
route
.
customTransition
!.
buildTransition
(
context
,
finalCurve
,
route
.
alignment
,
animation
,
secondaryAnimation
,
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
,
);
}
/// Apply the curve by default...
final
iosAnimation
=
animation
;
animation
=
CurvedAnimation
(
parent:
animation
,
curve:
finalCurve
);
switch
(
route
.
transition
??
Get
.
defaultTransition
)
{
case
Transition
.
leftToRight
:
return
SlideLeftTransition
().
buildTransitions
(
context
,
route
.
curve
,
route
.
alignment
,
animation
,
secondaryAnimation
,
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
);
case
Transition
.
downToUp
:
return
SlideDownTransition
().
buildTransitions
(
context
,
route
.
curve
,
route
.
alignment
,
animation
,
secondaryAnimation
,
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
);
case
Transition
.
upToDown
:
return
SlideTopTransition
().
buildTransitions
(
context
,
route
.
curve
,
route
.
alignment
,
animation
,
secondaryAnimation
,
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
);
case
Transition
.
noTransition
:
return
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
;
case
Transition
.
rightToLeft
:
return
SlideRightTransition
().
buildTransitions
(
context
,
route
.
curve
,
route
.
alignment
,
animation
,
secondaryAnimation
,
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
);
case
Transition
.
zoom
:
return
ZoomInTransition
().
buildTransitions
(
context
,
route
.
curve
,
route
.
alignment
,
animation
,
secondaryAnimation
,
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
);
case
Transition
.
fadeIn
:
return
FadeInTransition
().
buildTransitions
(
context
,
route
.
curve
,
route
.
alignment
,
animation
,
secondaryAnimation
,
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
);
case
Transition
.
rightToLeftWithFade
:
return
RightToLeftFadeTransition
().
buildTransitions
(
context
,
route
.
curve
,
route
.
alignment
,
animation
,
secondaryAnimation
,
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
);
case
Transition
.
leftToRightWithFade
:
return
LeftToRightFadeTransition
().
buildTransitions
(
context
,
route
.
curve
,
route
.
alignment
,
animation
,
secondaryAnimation
,
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
);
case
Transition
.
cupertino
:
return
CupertinoPageTransition
(
primaryRouteAnimation:
animation
,
secondaryRouteAnimation:
secondaryAnimation
,
linearTransition:
linearTransition
,
child:
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
,
),
);
case
Transition
.
size
:
return
SizeTransitions
().
buildTransitions
(
context
,
route
.
curve
!,
route
.
alignment
,
animation
,
secondaryAnimation
,
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
);
case
Transition
.
fade
:
return
FadeUpwardsPageTransitionsBuilder
().
buildTransitions
(
route
,
context
,
animation
,
secondaryAnimation
,
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
);
case
Transition
.
topLevel
:
return
ZoomPageTransitionsBuilder
().
buildTransitions
(
route
,
context
,
animation
,
secondaryAnimation
,
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
);
case
Transition
.
native
:
return
PageTransitionsTheme
().
buildTransitions
(
route
,
context
,
iosAnimation
,
secondaryAnimation
,
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
);
default
:
if
(
Get
.
customTransition
!=
null
)
{
return
Get
.
customTransition
!.
buildTransition
(
context
,
route
.
curve
,
route
.
alignment
,
animation
,
secondaryAnimation
,
child
);
}
return
PageTransitionsTheme
().
buildTransitions
(
route
,
context
,
iosAnimation
,
secondaryAnimation
,
route
.
popGesture
??
Get
.
defaultPopGesture
?
CupertinoBackGestureDetector
<
T
>(
gestureWidth:
route
.
gestureWidth
,
enabledCallback:
()
=>
_isPopGestureEnabled
<
T
>(
route
),
onStartPopGesture:
()
=>
_startPopGesture
<
T
>(
route
),
child:
child
)
:
child
);
}
}
}
@override
Widget
buildTransitions
(
BuildContext
context
,
Animation
<
double
>
animation
,
Animation
<
double
>
secondaryAnimation
,
Widget
child
)
{
return
buildPageTransitions
<
T
>(
this
,
context
,
animation
,
secondaryAnimation
,
child
);
}
}
class
CupertinoBackGestureDetector
<
T
>
extends
StatefulWidget
{
const
CupertinoBackGestureDetector
({
Key
?
key
,
required
this
.
enabledCallback
,
required
this
.
onStartPopGesture
,
required
this
.
child
,
required
this
.
gestureWidth
,
})
:
super
(
key:
key
);
final
Widget
child
;
final
double
gestureWidth
;
final
ValueGetter
<
bool
>
enabledCallback
;
final
ValueGetter
<
CupertinoBackGestureController
<
T
>>
onStartPopGesture
;
@override
CupertinoBackGestureDetectorState
<
T
>
createState
()
=>
CupertinoBackGestureDetectorState
<
T
>();
}
class
CupertinoBackGestureDetectorState
<
T
>
extends
State
<
CupertinoBackGestureDetector
<
T
>>
{
CupertinoBackGestureController
<
T
>?
_backGestureController
;
late
HorizontalDragGestureRecognizer
_recognizer
;
@override
void
initState
()
{
super
.
initState
();
_recognizer
=
HorizontalDragGestureRecognizer
(
debugOwner:
this
)
..
onStart
=
_handleDragStart
..
onUpdate
=
_handleDragUpdate
..
onEnd
=
_handleDragEnd
..
onCancel
=
_handleDragCancel
;
}
@override
void
dispose
()
{
_recognizer
.
dispose
();
super
.
dispose
();
}
void
_handleDragStart
(
DragStartDetails
details
)
{
assert
(
mounted
);
assert
(
_backGestureController
==
null
);
_backGestureController
=
widget
.
onStartPopGesture
();
}
void
_handleDragUpdate
(
DragUpdateDetails
details
)
{
assert
(
mounted
);
assert
(
_backGestureController
!=
null
);
_backGestureController
!.
dragUpdate
(
_convertToLogical
(
details
.
primaryDelta
!
/
context
.
size
!.
width
));
}
void
_handleDragEnd
(
DragEndDetails
details
)
{
assert
(
mounted
);
assert
(
_backGestureController
!=
null
);
_backGestureController
!.
dragEnd
(
_convertToLogical
(
details
.
velocity
.
pixelsPerSecond
.
dx
/
context
.
size
!.
width
));
_backGestureController
=
null
;
}
void
_handleDragCancel
()
{
assert
(
mounted
);
// This can be called even if start is not called, paired with
// the "down" event
// that we don't consider here.
_backGestureController
?.
dragEnd
(
0.0
);
_backGestureController
=
null
;
}
void
_handlePointerDown
(
PointerDownEvent
event
)
{
if
(
widget
.
enabledCallback
())
_recognizer
.
addPointer
(
event
);
}
double
_convertToLogical
(
double
value
)
{
switch
(
Directionality
.
of
(
context
))
{
case
TextDirection
.
rtl
:
return
-
value
;
case
TextDirection
.
ltr
:
return
value
;
}
}
@override
Widget
build
(
BuildContext
context
)
{
assert
(
debugCheckHasDirectionality
(
context
));
// For devices with notches, the drag area needs to be larger on the side
// that has the notch.
var
dragAreaWidth
=
Directionality
.
of
(
context
)
==
TextDirection
.
ltr
?
MediaQuery
.
of
(
context
).
padding
.
left
:
MediaQuery
.
of
(
context
).
padding
.
right
;
dragAreaWidth
=
max
(
dragAreaWidth
,
widget
.
gestureWidth
);
return
Stack
(
fit:
StackFit
.
passthrough
,
children:
<
Widget
>[
widget
.
child
,
PositionedDirectional
(
start:
0.0
,
width:
dragAreaWidth
,
top:
0.0
,
bottom:
0.0
,
child:
Listener
(
onPointerDown:
_handlePointerDown
,
behavior:
HitTestBehavior
.
translucent
,
),
),
],
);
}
}
class
CupertinoBackGestureController
<
T
>
{
/// Creates a controller for an iOS-style back gesture.
///
/// The [navigator] and [controller] arguments must not be null.
CupertinoBackGestureController
({
required
this
.
navigator
,
required
this
.
controller
,
})
{
navigator
.
didStartUserGesture
();
}
final
AnimationController
controller
;
final
NavigatorState
navigator
;
/// The drag gesture has changed by [fractionalDelta]. The total range of the
/// drag should be 0.0 to 1.0.
void
dragUpdate
(
double
delta
)
{
controller
.
value
-=
delta
;
}
/// The drag gesture has ended with a horizontal motion of
/// [fractionalVelocity] as a fraction of screen width per second.
void
dragEnd
(
double
velocity
)
{
// Fling in the appropriate direction.
// AnimationController.fling is guaranteed to
// take at least one frame.
//
// This curve has been determined through rigorously eyeballing native iOS
// animations.
const
Curve
animationCurve
=
Curves
.
fastLinearToSlowEaseIn
;
final
bool
animateForward
;
// If the user releases the page before mid screen with sufficient velocity,
// or after mid screen, we should animate the page out. Otherwise, the page
// should be animated back in.
if
(
velocity
.
abs
()
>=
_kMinFlingVelocity
)
{
animateForward
=
velocity
<=
0
;
}
else
{
animateForward
=
controller
.
value
>
0.5
;
}
if
(
animateForward
)
{
// The closer the panel is to dismissing, the shorter the animation is.
// We want to cap the animation time, but we want to use a linear curve
// to determine it.
final
droppedPageForwardAnimationTime
=
min
(
lerpDouble
(
_kMaxDroppedSwipePageForwardAnimationTime
,
0
,
controller
.
value
)!
.
floor
(),
_kMaxPageBackAnimationTime
,
);
controller
.
animateTo
(
1.0
,
duration:
Duration
(
milliseconds:
droppedPageForwardAnimationTime
),
curve:
animationCurve
);
}
else
{
// This route is destined to pop at this point. Reuse navigator's pop.
navigator
.
pop
();
// The popping may have finished inline if already at the
// target destination.
if
(
controller
.
isAnimating
)
{
// Otherwise, use a custom popping animation duration and curve.
final
droppedPageBackAnimationTime
=
lerpDouble
(
0
,
_kMaxDroppedSwipePageForwardAnimationTime
,
controller
.
value
)!
.
floor
();
controller
.
animateBack
(
0.0
,
duration:
Duration
(
milliseconds:
droppedPageBackAnimationTime
),
curve:
animationCurve
);
}
}
if
(
controller
.
isAnimating
)
{
// Keep the userGestureInProgress in true state so we don't change the
// curve of the page transition mid-flight since CupertinoPageTransition
// depends on userGestureInProgress.
late
AnimationStatusListener
animationStatusCallback
;
animationStatusCallback
=
(
status
)
{
navigator
.
didStopUserGesture
();
controller
.
removeStatusListener
(
animationStatusCallback
);
};
controller
.
addStatusListener
(
animationStatusCallback
);
}
else
{
navigator
.
didStopUserGesture
();
}
}
}
...
...
lib/get_navigation/src/routes/route_middleware.dart
View file @
3156b6f
...
...
@@ -158,14 +158,14 @@ class MiddlewareRunner {
class
PageRedirect
{
GetPage
?
route
;
GetPage
?
unknownRoute
;
RouteSettings
settings
;
RouteSettings
?
settings
;
bool
isUnknown
;
PageRedirect
(
this
.
settings
,
this
.
unknownRoute
,
{
this
.
isUnknown
=
false
,
PageRedirect
({
this
.
route
,
this
.
unknownRoute
,
this
.
isUnknown
=
false
,
this
.
settings
,
});
// redirect all pages that needes redirecting
...
...
@@ -178,11 +178,36 @@ class PageRedirect {
settings:
isUnknown
?
RouteSettings
(
name:
_r
.
name
,
arguments:
settings
.
arguments
,
arguments:
settings
!
.
arguments
,
)
:
settings
,
curve:
_r
.
curve
,
opaque:
_r
.
opaque
,
gestureWidth:
_r
.
gestureWidth
,
customTransition:
_r
.
customTransition
,
binding:
_r
.
binding
,
bindings:
_r
.
bindings
,
transitionDuration:
_r
.
transitionDuration
??
Get
.
defaultTransitionDuration
,
transition:
_r
.
transition
,
popGesture:
_r
.
popGesture
,
fullscreenDialog:
_r
.
fullscreenDialog
,
middlewares:
_r
.
middlewares
,
);
}
// redirect all pages that needes redirecting
GetPageRoute
<
T
>
getPageToRoute
<
T
>(
GetPage
rou
,
GetPage
?
unk
)
{
while
(
needRecheck
())
{}
final
_r
=
(
isUnknown
?
unk
:
rou
)!;
return
GetPageRoute
<
T
>(
page:
_r
.
page
,
parameter:
_r
.
parameter
,
settings:
_r
,
curve:
_r
.
curve
,
gestureWidth:
_r
.
gestureWidth
,
opaque:
_r
.
opaque
,
customTransition:
_r
.
customTransition
,
binding:
_r
.
binding
,
bindings:
_r
.
bindings
,
...
...
@@ -197,7 +222,10 @@ class PageRedirect {
/// check if redirect is needed
bool
needRecheck
()
{
final
match
=
Get
.
routeTree
.
matchRoute
(
settings
.
name
!);
if
(
settings
==
null
&&
route
!=
null
)
{
settings
=
route
;
}
final
match
=
Get
.
routeTree
.
matchRoute
(
settings
!.
name
!);
Get
.
parameters
=
match
.
parameters
;
// No Match found
...
...
@@ -214,7 +242,7 @@ class PageRedirect {
if
(
match
.
route
!.
middlewares
==
null
||
match
.
route
!.
middlewares
!.
isEmpty
)
{
return
false
;
}
final
newSettings
=
runner
.
runRedirect
(
settings
.
name
);
final
newSettings
=
runner
.
runRedirect
(
settings
!
.
name
);
if
(
newSettings
==
null
)
{
return
false
;
}
...
...
Please
register
or
login
to post a comment