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-11-25 13:28:55 -0300
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
955c18da44e7fd3a3edfe2b38c1c7ef715944986
955c18da
1 parent
e7c29169
prepare snackbar api to getx 5
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
1069 additions
and
1139 deletions
lib/get_navigation/get_navigation.dart
lib/get_navigation/src/extension_navigation.dart
lib/get_navigation/src/root/get_material_app.dart
lib/get_navigation/src/root/root_controller.dart
lib/get_navigation/src/routes/observers/route_observer.dart
lib/get_navigation/src/snackbar/snack.dart
lib/get_navigation/src/snackbar/snack_route.dart
lib/get_navigation/src/snackbar/snackbar_controller.dart
lib/get_navigation/get_navigation.dart
View file @
955c18d
...
...
@@ -17,4 +17,3 @@ export 'src/routes/observers/route_observer.dart';
export
'src/routes/route_middleware.dart'
;
export
'src/routes/transitions_type.dart'
;
export
'src/snackbar/snack.dart'
;
export
'src/snackbar/snack_route.dart'
;
...
...
lib/get_navigation/src/extension_navigation.dart
View file @
955c18d
...
...
@@ -11,243 +11,56 @@ import 'dialog/dialog_route.dart';
import
'root/parse_route.dart'
;
import
'root/root_controller.dart'
;
import
'routes/transitions_type.dart'
;
import
'snackbar/snackbar_controller.dart'
;
extension
ExtensionSnackbar
on
GetInterface
{
void
rawSnackbar
({
String
?
title
,
String
?
message
,
Widget
?
titleText
,
Widget
?
messageText
,
Widget
?
icon
,
bool
instantInit
=
true
,
bool
shouldIconPulse
=
true
,
double
?
maxWidth
,
EdgeInsets
margin
=
const
EdgeInsets
.
all
(
0.0
),
EdgeInsets
padding
=
const
EdgeInsets
.
all
(
16
),
double
borderRadius
=
0.0
,
Color
?
borderColor
,
double
borderWidth
=
1.0
,
Color
backgroundColor
=
const
Color
(
0xFF303030
),
Color
?
leftBarIndicatorColor
,
List
<
BoxShadow
>?
boxShadows
,
Gradient
?
backgroundGradient
,
Widget
?
mainButton
,
OnTap
?
onTap
,
Duration
duration
=
const
Duration
(
seconds:
3
),
bool
isDismissible
=
true
,
SnackDismissDirection
dismissDirection
=
SnackDismissDirection
.
VERTICAL
,
bool
showProgressIndicator
=
false
,
AnimationController
?
progressIndicatorController
,
Color
?
progressIndicatorBackgroundColor
,
Animation
<
Color
>?
progressIndicatorValueColor
,
SnackPosition
snackPosition
=
SnackPosition
.
BOTTOM
,
SnackStyle
snackStyle
=
SnackStyle
.
FLOATING
,
Curve
forwardAnimationCurve
=
Curves
.
easeOutCirc
,
Curve
reverseAnimationCurve
=
Curves
.
easeOutCirc
,
Duration
animationDuration
=
const
Duration
(
seconds:
1
),
SnackbarStatusCallback
?
snackbarStatus
,
double
?
barBlur
=
0.0
,
double
overlayBlur
=
0.0
,
Color
?
overlayColor
,
Form
?
userInputForm
,
})
async
{
final
getBar
=
GetBar
(
snackbarStatus:
snackbarStatus
,
title:
title
,
message:
message
,
titleText:
titleText
,
messageText:
messageText
,
snackPosition:
snackPosition
,
borderRadius:
borderRadius
,
margin:
margin
,
duration:
duration
,
barBlur:
barBlur
,
backgroundColor:
backgroundColor
,
icon:
icon
,
shouldIconPulse:
shouldIconPulse
,
maxWidth:
maxWidth
,
padding:
padding
,
borderColor:
borderColor
,
borderWidth:
borderWidth
,
leftBarIndicatorColor:
leftBarIndicatorColor
,
boxShadows:
boxShadows
,
backgroundGradient:
backgroundGradient
,
mainButton:
mainButton
,
onTap:
onTap
,
isDismissible:
isDismissible
,
dismissDirection:
dismissDirection
,
showProgressIndicator:
showProgressIndicator
,
progressIndicatorController:
progressIndicatorController
,
progressIndicatorBackgroundColor:
progressIndicatorBackgroundColor
,
progressIndicatorValueColor:
progressIndicatorValueColor
,
snackStyle:
snackStyle
,
forwardAnimationCurve:
forwardAnimationCurve
,
reverseAnimationCurve:
reverseAnimationCurve
,
animationDuration:
animationDuration
,
overlayBlur:
overlayBlur
,
overlayColor:
overlayColor
,
userInputForm:
userInputForm
,
);
if
(
instantInit
)
{
getBar
.
show
();
}
else
{
SchedulerBinding
.
instance
!.
addPostFrameCallback
((
_
)
{
getBar
.
show
();
});
}
}
Future
<
T
?>?
showSnackbar
<
T
>(
GetBar
snackbar
)
{
return
key
.
currentState
?.
push
(
SnackRoute
<
T
>(
snack:
snackbar
));
}
void
snackbar
<
T
>(
String
title
,
String
message
,
{
Color
?
colorText
,
Duration
?
duration
,
/// It replaces the Flutter Navigator, but needs no context.
/// You can to use navigator.push(YourRoute()) rather
/// Navigator.push(context, YourRoute());
NavigatorState
?
get
navigator
=>
GetNavigation
(
Get
).
key
.
currentState
;
/// with instantInit = false you can put snackbar on initState
bool
instantInit
=
true
,
SnackPosition
?
snackPosition
,
Widget
?
titleText
,
Widget
?
messageText
,
Widget
?
icon
,
bool
?
shouldIconPulse
,
double
?
maxWidth
,
EdgeInsets
?
margin
,
EdgeInsets
?
padding
,
double
?
borderRadius
,
Color
?
borderColor
,
double
?
borderWidth
,
extension
ExtensionBottomSheet
on
GetInterface
{
Future
<
T
?>
bottomSheet
<
T
>(
Widget
bottomsheet
,
{
Color
?
backgroundColor
,
Color
?
leftBarIndicatorColor
,
List
<
BoxShadow
>?
boxShadows
,
Gradient
?
backgroundGradient
,
TextButton
?
mainButton
,
OnTap
?
onTap
,
bool
?
isDismissible
,
bool
?
showProgressIndicator
,
SnackDismissDirection
?
dismissDirection
,
AnimationController
?
progressIndicatorController
,
Color
?
progressIndicatorBackgroundColor
,
Animation
<
Color
>?
progressIndicatorValueColor
,
SnackStyle
?
snackStyle
,
Curve
?
forwardAnimationCurve
,
Curve
?
reverseAnimationCurve
,
Duration
?
animationDuration
,
double
?
barBlur
,
double
?
overlayBlur
,
SnackbarStatusCallback
?
snackbarStatus
,
Color
?
overlayColor
,
Form
?
userInputForm
,
})
async
{
final
getBar
=
GetBar
(
snackbarStatus:
snackbarStatus
,
titleText:
titleText
??
Text
(
title
,
style:
TextStyle
(
color:
colorText
??
iconColor
??
Colors
.
black
,
fontWeight:
FontWeight
.
w800
,
fontSize:
16
,
),
),
messageText:
messageText
??
Text
(
message
,
style:
TextStyle
(
color:
colorText
??
iconColor
??
Colors
.
black
,
fontWeight:
FontWeight
.
w300
,
fontSize:
14
,
),
),
snackPosition:
snackPosition
??
SnackPosition
.
TOP
,
borderRadius:
borderRadius
??
15
,
margin:
margin
??
EdgeInsets
.
symmetric
(
horizontal:
10
),
duration:
duration
??
Duration
(
seconds:
3
),
barBlur:
barBlur
??
7.0
,
backgroundColor:
backgroundColor
??
Colors
.
grey
.
withOpacity
(
0.2
),
icon:
icon
,
shouldIconPulse:
shouldIconPulse
??
true
,
maxWidth:
maxWidth
,
padding:
padding
??
EdgeInsets
.
all
(
16
),
borderColor:
borderColor
,
borderWidth:
borderWidth
,
leftBarIndicatorColor:
leftBarIndicatorColor
,
boxShadows:
boxShadows
,
backgroundGradient:
backgroundGradient
,
mainButton:
mainButton
,
onTap:
onTap
,
isDismissible:
isDismissible
??
true
,
dismissDirection:
dismissDirection
??
SnackDismissDirection
.
VERTICAL
,
showProgressIndicator:
showProgressIndicator
??
false
,
progressIndicatorController:
progressIndicatorController
,
progressIndicatorBackgroundColor:
progressIndicatorBackgroundColor
,
progressIndicatorValueColor:
progressIndicatorValueColor
,
snackStyle:
snackStyle
??
SnackStyle
.
FLOATING
,
forwardAnimationCurve:
forwardAnimationCurve
??
Curves
.
easeOutCirc
,
reverseAnimationCurve:
reverseAnimationCurve
??
Curves
.
easeOutCirc
,
animationDuration:
animationDuration
??
Duration
(
seconds:
1
),
overlayBlur:
overlayBlur
??
0.0
,
overlayColor:
overlayColor
??
Colors
.
transparent
,
userInputForm:
userInputForm
);
if
(
instantInit
)
{
showSnackbar
<
T
>(
getBar
);
}
else
{
routing
.
isSnackbar
=
true
;
SchedulerBinding
.
instance
!.
addPostFrameCallback
((
_
)
{
showSnackbar
<
T
>(
getBar
);
});
}
}
}
extension
OverlayExt
on
GetInterface
{
Future
<
T
>
showOverlay
<
T
>({
required
Future
<
T
>
Function
()
asyncFunction
,
Color
opacityColor
=
Colors
.
black
,
Widget
?
loadingWidget
,
double
opacity
=
.
5
,
})
async
{
final
navigatorState
=
Navigator
.
of
(
Get
.
overlayContext
!,
rootNavigator:
false
);
final
overlayState
=
navigatorState
.
overlay
!;
final
overlayEntryOpacity
=
OverlayEntry
(
builder:
(
context
)
{
return
Opacity
(
opacity:
opacity
,
child:
Container
(
color:
opacityColor
,
));
});
final
overlayEntryLoader
=
OverlayEntry
(
builder:
(
context
)
{
return
loadingWidget
??
Center
(
child:
Container
(
height:
90
,
width:
90
,
child:
Text
(
'Loading...'
),
));
});
overlayState
.
insert
(
overlayEntryOpacity
);
overlayState
.
insert
(
overlayEntryLoader
);
T
data
;
double
?
elevation
,
bool
persistent
=
true
,
ShapeBorder
?
shape
,
Clip
?
clipBehavior
,
Color
?
barrierColor
,
bool
?
ignoreSafeArea
,
bool
isScrollControlled
=
false
,
bool
useRootNavigator
=
false
,
bool
isDismissible
=
true
,
bool
enableDrag
=
true
,
RouteSettings
?
settings
,
Duration
?
enterBottomSheetDuration
,
Duration
?
exitBottomSheetDuration
,
})
{
return
Navigator
.
of
(
overlayContext
!,
rootNavigator:
useRootNavigator
)
.
push
(
GetModalBottomSheetRoute
<
T
>(
builder:
(
_
)
=>
bottomsheet
,
isPersistent:
persistent
,
// theme: Theme.of(key.currentContext, shadowThemeOnly: true),
theme:
Theme
.
of
(
key
.
currentContext
!),
isScrollControlled:
isScrollControlled
,
try
{
data
=
await
asyncFunction
();
}
on
Exception
catch
(
_
)
{
overlayEntryLoader
.
remove
();
overlayEntryOpacity
.
remove
();
rethrow
;
}
barrierLabel:
MaterialLocalizations
.
of
(
key
.
currentContext
!)
.
modalBarrierDismissLabel
,
overlayEntryLoader
.
remove
();
overlayEntryOpacity
.
remove
();
return
data
;
backgroundColor:
backgroundColor
??
Colors
.
transparent
,
elevation:
elevation
,
shape:
shape
,
removeTop:
ignoreSafeArea
??
true
,
clipBehavior:
clipBehavior
,
isDismissible:
isDismissible
,
modalBarrierColor:
barrierColor
,
settings:
settings
,
enableDrag:
enableDrag
,
enterBottomSheetDuration:
enterBottomSheetDuration
??
const
Duration
(
milliseconds:
250
),
exitBottomSheetDuration:
exitBottomSheetDuration
??
const
Duration
(
milliseconds:
200
),
));
}
}
...
...
@@ -378,7 +191,7 @@ extension ExtensionDialog on GetInterface {
padding:
EdgeInsets
.
symmetric
(
horizontal:
10
,
vertical:
8
),
shape:
RoundedRectangleBorder
(
side:
BorderSide
(
color:
buttonColor
??
theme
.
accentColor
,
color:
buttonColor
??
theme
.
colorScheme
.
secondary
,
width:
2
,
style:
BorderStyle
.
solid
),
borderRadius:
BorderRadius
.
circular
(
100
)),
...
...
@@ -389,7 +202,8 @@ extension ExtensionDialog on GetInterface {
},
child:
Text
(
textCancel
??
"Cancel"
,
style:
TextStyle
(
color:
cancelTextColor
??
theme
.
accentColor
),
style:
TextStyle
(
color:
cancelTextColor
??
theme
.
colorScheme
.
secondary
),
),
));
}
...
...
@@ -397,113 +211,260 @@ extension ExtensionDialog on GetInterface {
if
(
confirm
!=
null
)
{
actions
.
add
(
confirm
);
}
else
{
if
(
leanConfirm
)
{
actions
.
add
(
TextButton
(
style:
TextButton
.
styleFrom
(
tapTargetSize:
MaterialTapTargetSize
.
shrinkWrap
,
backgroundColor:
buttonColor
??
theme
.
accentColor
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
100
)),
),
child:
Text
(
textConfirm
??
"Ok"
,
style:
TextStyle
(
color:
confirmTextColor
??
theme
.
backgroundColor
),
),
onPressed:
()
{
onConfirm
?.
call
();
}));
}
if
(
leanConfirm
)
{
actions
.
add
(
TextButton
(
style:
TextButton
.
styleFrom
(
tapTargetSize:
MaterialTapTargetSize
.
shrinkWrap
,
backgroundColor:
buttonColor
??
theme
.
colorScheme
.
secondary
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
circular
(
100
)),
),
child:
Text
(
textConfirm
??
"Ok"
,
style:
TextStyle
(
color:
confirmTextColor
??
theme
.
backgroundColor
),
),
onPressed:
()
{
onConfirm
?.
call
();
}));
}
}
Widget
baseAlertDialog
=
AlertDialog
(
titlePadding:
titlePadding
??
EdgeInsets
.
all
(
8
),
contentPadding:
contentPadding
??
EdgeInsets
.
all
(
8
),
backgroundColor:
backgroundColor
??
theme
.
dialogBackgroundColor
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
all
(
Radius
.
circular
(
radius
))),
title:
Text
(
title
,
textAlign:
TextAlign
.
center
,
style:
titleStyle
),
content:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
mainAxisSize:
MainAxisSize
.
min
,
children:
[
content
??
Text
(
middleText
,
textAlign:
TextAlign
.
center
,
style:
middleTextStyle
),
SizedBox
(
height:
16
),
ButtonTheme
(
minWidth:
78.0
,
height:
34.0
,
child:
Wrap
(
alignment:
WrapAlignment
.
center
,
spacing:
8
,
runSpacing:
8
,
children:
actions
,
),
)
],
),
// actions: actions, // ?? <Widget>[cancelButton, confirmButton],
buttonPadding:
EdgeInsets
.
zero
,
);
return
dialog
<
T
>(
onWillPop
!=
null
?
WillPopScope
(
onWillPop:
onWillPop
,
child:
baseAlertDialog
,
)
:
baseAlertDialog
,
barrierDismissible:
barrierDismissible
,
navigatorKey:
navigatorKey
,
);
}
}
extension
ExtensionSnackbar
on
GetInterface
{
void
rawSnackbar
({
String
?
title
,
String
?
message
,
Widget
?
titleText
,
Widget
?
messageText
,
Widget
?
icon
,
bool
instantInit
=
true
,
bool
shouldIconPulse
=
true
,
double
?
maxWidth
,
EdgeInsets
margin
=
const
EdgeInsets
.
all
(
0.0
),
EdgeInsets
padding
=
const
EdgeInsets
.
all
(
16
),
double
borderRadius
=
0.0
,
Color
?
borderColor
,
double
borderWidth
=
1.0
,
Color
backgroundColor
=
const
Color
(
0xFF303030
),
Color
?
leftBarIndicatorColor
,
List
<
BoxShadow
>?
boxShadows
,
Gradient
?
backgroundGradient
,
Widget
?
mainButton
,
OnTap
?
onTap
,
Duration
duration
=
const
Duration
(
seconds:
3
),
bool
isDismissible
=
true
,
SnackDismissDirection
dismissDirection
=
SnackDismissDirection
.
VERTICAL
,
bool
showProgressIndicator
=
false
,
AnimationController
?
progressIndicatorController
,
Color
?
progressIndicatorBackgroundColor
,
Animation
<
Color
>?
progressIndicatorValueColor
,
SnackPosition
snackPosition
=
SnackPosition
.
BOTTOM
,
SnackStyle
snackStyle
=
SnackStyle
.
FLOATING
,
Curve
forwardAnimationCurve
=
Curves
.
easeOutCirc
,
Curve
reverseAnimationCurve
=
Curves
.
easeOutCirc
,
Duration
animationDuration
=
const
Duration
(
seconds:
1
),
SnackbarStatusCallback
?
snackbarStatus
,
double
?
barBlur
=
0.0
,
double
overlayBlur
=
0.0
,
Color
?
overlayColor
,
Form
?
userInputForm
,
})
async
{
final
getBar
=
GetBar
(
snackbarStatus:
snackbarStatus
,
title:
title
,
message:
message
,
titleText:
titleText
,
messageText:
messageText
,
snackPosition:
snackPosition
,
borderRadius:
borderRadius
,
margin:
margin
,
duration:
duration
,
barBlur:
barBlur
,
backgroundColor:
backgroundColor
,
icon:
icon
,
shouldIconPulse:
shouldIconPulse
,
maxWidth:
maxWidth
,
padding:
padding
,
borderColor:
borderColor
,
borderWidth:
borderWidth
,
leftBarIndicatorColor:
leftBarIndicatorColor
,
boxShadows:
boxShadows
,
backgroundGradient:
backgroundGradient
,
mainButton:
mainButton
,
onTap:
onTap
,
isDismissible:
isDismissible
,
dismissDirection:
dismissDirection
,
showProgressIndicator:
showProgressIndicator
,
progressIndicatorController:
progressIndicatorController
,
progressIndicatorBackgroundColor:
progressIndicatorBackgroundColor
,
progressIndicatorValueColor:
progressIndicatorValueColor
,
snackStyle:
snackStyle
,
forwardAnimationCurve:
forwardAnimationCurve
,
reverseAnimationCurve:
reverseAnimationCurve
,
animationDuration:
animationDuration
,
overlayBlur:
overlayBlur
,
overlayColor:
overlayColor
,
userInputForm:
userInputForm
,
);
if
(
instantInit
)
{
getBar
.
show
();
}
else
{
SchedulerBinding
.
instance
!.
addPostFrameCallback
((
_
)
{
getBar
.
show
();
});
}
}
Widget
baseAlertDialog
=
AlertDialog
(
titlePadding:
titlePadding
??
EdgeInsets
.
all
(
8
),
contentPadding:
contentPadding
??
EdgeInsets
.
all
(
8
),
backgroundColor:
backgroundColor
??
theme
.
dialogBackgroundColor
,
shape:
RoundedRectangleBorder
(
borderRadius:
BorderRadius
.
all
(
Radius
.
circular
(
radius
))),
title:
Text
(
title
,
textAlign:
TextAlign
.
center
,
style:
titleStyle
),
content:
Column
(
crossAxisAlignment:
CrossAxisAlignment
.
center
,
mainAxisSize:
MainAxisSize
.
min
,
children:
[
content
??
Text
(
middleText
,
textAlign:
TextAlign
.
center
,
style:
middleTextStyle
),
SizedBox
(
height:
16
),
ButtonTheme
(
minWidth:
78.0
,
height:
34.0
,
child:
Wrap
(
alignment:
WrapAlignment
.
center
,
spacing:
8
,
runSpacing:
8
,
children:
actions
,
),
)
],
),
// actions: actions, // ?? <Widget>[cancelButton, confirmButton],
buttonPadding:
EdgeInsets
.
zero
,
);
return
dialog
<
T
>(
onWillPop
!=
null
?
WillPopScope
(
onWillPop:
onWillPop
,
child:
baseAlertDialog
,
)
:
baseAlertDialog
,
barrierDismissible:
barrierDismissible
,
navigatorKey:
navigatorKey
,
);
Future
<
void
>
showSnackbar
<
T
>(
GetBar
snackbar
)
{
return
SnackbarController
(
snackbar
).
show
();
}
}
extension
ExtensionBottomSheet
on
GetInterface
{
Future
<
T
?>
bottomSheet
<
T
>(
Widget
bottomsheet
,
{
Color
?
backgroundColor
,
double
?
elevation
,
bool
persistent
=
true
,
ShapeBorder
?
shape
,
Clip
?
clipBehavior
,
Color
?
barrierColor
,
bool
?
ignoreSafeArea
,
bool
isScrollControlled
=
false
,
bool
useRootNavigator
=
false
,
bool
isDismissible
=
true
,
bool
enableDrag
=
true
,
RouteSettings
?
settings
,
Duration
?
enterBottomSheetDuration
,
Duration
?
exitBottomSheetDuration
,
})
{
return
Navigator
.
of
(
overlayContext
!,
rootNavigator:
useRootNavigator
)
.
push
(
GetModalBottomSheetRoute
<
T
>(
builder:
(
_
)
=>
bottomsheet
,
isPersistent:
persistent
,
// theme: Theme.of(key.currentContext, shadowThemeOnly: true),
theme:
Theme
.
of
(
key
.
currentContext
!),
isScrollControlled:
isScrollControlled
,
void
snackbar
<
T
>(
String
title
,
String
message
,
{
Color
?
colorText
,
Duration
?
duration
,
barrierLabel:
MaterialLocalizations
.
of
(
key
.
currentContext
!)
.
modalBarrierDismissLabel
,
/// with instantInit = false you can put snackbar on initState
bool
instantInit
=
true
,
SnackPosition
?
snackPosition
,
Widget
?
titleText
,
Widget
?
messageText
,
Widget
?
icon
,
bool
?
shouldIconPulse
,
double
?
maxWidth
,
EdgeInsets
?
margin
,
EdgeInsets
?
padding
,
double
?
borderRadius
,
Color
?
borderColor
,
double
?
borderWidth
,
Color
?
backgroundColor
,
Color
?
leftBarIndicatorColor
,
List
<
BoxShadow
>?
boxShadows
,
Gradient
?
backgroundGradient
,
TextButton
?
mainButton
,
OnTap
?
onTap
,
bool
?
isDismissible
,
bool
?
showProgressIndicator
,
SnackDismissDirection
?
dismissDirection
,
AnimationController
?
progressIndicatorController
,
Color
?
progressIndicatorBackgroundColor
,
Animation
<
Color
>?
progressIndicatorValueColor
,
SnackStyle
?
snackStyle
,
Curve
?
forwardAnimationCurve
,
Curve
?
reverseAnimationCurve
,
Duration
?
animationDuration
,
double
?
barBlur
,
double
?
overlayBlur
,
SnackbarStatusCallback
?
snackbarStatus
,
Color
?
overlayColor
,
Form
?
userInputForm
,
})
async
{
final
getBar
=
GetBar
(
snackbarStatus:
snackbarStatus
,
titleText:
titleText
??
Text
(
title
,
style:
TextStyle
(
color:
colorText
??
iconColor
??
Colors
.
black
,
fontWeight:
FontWeight
.
w800
,
fontSize:
16
,
),
),
messageText:
messageText
??
Text
(
message
,
style:
TextStyle
(
color:
colorText
??
iconColor
??
Colors
.
black
,
fontWeight:
FontWeight
.
w300
,
fontSize:
14
,
),
),
snackPosition:
snackPosition
??
SnackPosition
.
TOP
,
borderRadius:
borderRadius
??
15
,
margin:
margin
??
EdgeInsets
.
symmetric
(
horizontal:
10
),
duration:
duration
??
Duration
(
seconds:
3
),
barBlur:
barBlur
??
7.0
,
backgroundColor:
backgroundColor
??
Colors
.
grey
.
withOpacity
(
0.2
),
icon:
icon
,
shouldIconPulse:
shouldIconPulse
??
true
,
maxWidth:
maxWidth
,
padding:
padding
??
EdgeInsets
.
all
(
16
),
borderColor:
borderColor
,
borderWidth:
borderWidth
,
leftBarIndicatorColor:
leftBarIndicatorColor
,
boxShadows:
boxShadows
,
backgroundGradient:
backgroundGradient
,
mainButton:
mainButton
,
onTap:
onTap
,
isDismissible:
isDismissible
??
true
,
dismissDirection:
dismissDirection
??
SnackDismissDirection
.
VERTICAL
,
showProgressIndicator:
showProgressIndicator
??
false
,
progressIndicatorController:
progressIndicatorController
,
progressIndicatorBackgroundColor:
progressIndicatorBackgroundColor
,
progressIndicatorValueColor:
progressIndicatorValueColor
,
snackStyle:
snackStyle
??
SnackStyle
.
FLOATING
,
forwardAnimationCurve:
forwardAnimationCurve
??
Curves
.
easeOutCirc
,
reverseAnimationCurve:
reverseAnimationCurve
??
Curves
.
easeOutCirc
,
animationDuration:
animationDuration
??
Duration
(
seconds:
1
),
overlayBlur:
overlayBlur
??
0.0
,
overlayColor:
overlayColor
??
Colors
.
transparent
,
userInputForm:
userInputForm
);
backgroundColor:
backgroundColor
??
Colors
.
transparent
,
elevation:
elevation
,
shape:
shape
,
removeTop:
ignoreSafeArea
??
true
,
clipBehavior:
clipBehavior
,
isDismissible:
isDismissible
,
modalBarrierColor:
barrierColor
,
settings:
settings
,
enableDrag:
enableDrag
,
enterBottomSheetDuration:
enterBottomSheetDuration
??
const
Duration
(
milliseconds:
250
),
exitBottomSheetDuration:
exitBottomSheetDuration
??
const
Duration
(
milliseconds:
200
),
));
if
(
instantInit
)
{
showSnackbar
<
T
>(
getBar
);
}
else
{
//routing.isSnackbar = true;
SchedulerBinding
.
instance
!.
addPostFrameCallback
((
_
)
{
showSnackbar
<
T
>(
getBar
);
});
}
}
}
...
...
@@ -1134,8 +1095,9 @@ you can only use widgets and widget functions here''';
/// give name from previous route
String
get
previousRoute
=>
routing
.
previous
;
///TODO: made snackbar 2.0 trackeables
/// check if snackbar is open
bool
?
get
isSnackbarOpen
=>
routing
.
isSnackbar
;
bool
?
get
isSnackbarOpen
=>
true
;
//
routing.isSnackbar;
/// check if dialog is open
bool
?
get
isDialogOpen
=>
routing
.
isDialog
;
...
...
@@ -1341,7 +1303,48 @@ extension NavTwoExt on GetInterface {
}
}
/// It replaces the Flutter Navigator, but needs no context.
/// You can to use navigator.push(YourRoute()) rather
/// Navigator.push(context, YourRoute());
NavigatorState
?
get
navigator
=>
GetNavigation
(
Get
).
key
.
currentState
;
extension
OverlayExt
on
GetInterface
{
Future
<
T
>
showOverlay
<
T
>({
required
Future
<
T
>
Function
()
asyncFunction
,
Color
opacityColor
=
Colors
.
black
,
Widget
?
loadingWidget
,
double
opacity
=
.
5
,
})
async
{
final
navigatorState
=
Navigator
.
of
(
Get
.
overlayContext
!,
rootNavigator:
false
);
final
overlayState
=
navigatorState
.
overlay
!;
final
overlayEntryOpacity
=
OverlayEntry
(
builder:
(
context
)
{
return
Opacity
(
opacity:
opacity
,
child:
Container
(
color:
opacityColor
,
));
});
final
overlayEntryLoader
=
OverlayEntry
(
builder:
(
context
)
{
return
loadingWidget
??
Center
(
child:
Container
(
height:
90
,
width:
90
,
child:
Text
(
'Loading...'
),
));
});
overlayState
.
insert
(
overlayEntryOpacity
);
overlayState
.
insert
(
overlayEntryLoader
);
T
data
;
try
{
data
=
await
asyncFunction
();
}
on
Exception
catch
(
_
)
{
overlayEntryLoader
.
remove
();
overlayEntryOpacity
.
remove
();
rethrow
;
}
overlayEntryLoader
.
remove
();
overlayEntryOpacity
.
remove
();
return
data
;
}
}
...
...
lib/get_navigation/src/root/get_material_app.dart
View file @
955c18d
...
...
@@ -10,6 +10,63 @@ import '../../get_navigation.dart';
import
'root_controller.dart'
;
class
GetMaterialApp
extends
StatelessWidget
{
final
GlobalKey
<
NavigatorState
>?
navigatorKey
;
final
GlobalKey
<
ScaffoldMessengerState
>?
scaffoldMessengerKey
;
final
Widget
?
home
;
final
Map
<
String
,
WidgetBuilder
>?
routes
;
final
String
?
initialRoute
;
final
RouteFactory
?
onGenerateRoute
;
final
InitialRouteListFactory
?
onGenerateInitialRoutes
;
final
RouteFactory
?
onUnknownRoute
;
final
List
<
NavigatorObserver
>?
navigatorObservers
;
final
TransitionBuilder
?
builder
;
final
String
title
;
final
GenerateAppTitle
?
onGenerateTitle
;
final
ThemeData
?
theme
;
final
ThemeData
?
darkTheme
;
final
ThemeMode
themeMode
;
final
CustomTransition
?
customTransition
;
final
Color
?
color
;
final
Map
<
String
,
Map
<
String
,
String
>>?
translationsKeys
;
final
Translations
?
translations
;
final
TextDirection
?
textDirection
;
final
Locale
?
locale
;
final
Locale
?
fallbackLocale
;
final
Iterable
<
LocalizationsDelegate
<
dynamic
>>?
localizationsDelegates
;
final
LocaleListResolutionCallback
?
localeListResolutionCallback
;
final
LocaleResolutionCallback
?
localeResolutionCallback
;
final
Iterable
<
Locale
>
supportedLocales
;
final
bool
showPerformanceOverlay
;
final
bool
checkerboardRasterCacheImages
;
final
bool
checkerboardOffscreenLayers
;
final
bool
showSemanticsDebugger
;
final
bool
debugShowCheckedModeBanner
;
final
Map
<
LogicalKeySet
,
Intent
>?
shortcuts
;
final
ScrollBehavior
?
scrollBehavior
;
final
ThemeData
?
highContrastTheme
;
final
ThemeData
?
highContrastDarkTheme
;
final
Map
<
Type
,
Action
<
Intent
>>?
actions
;
final
bool
debugShowMaterialGrid
;
final
ValueChanged
<
Routing
?>?
routingCallback
;
final
Transition
?
defaultTransition
;
final
bool
?
opaqueRoute
;
final
VoidCallback
?
onInit
;
final
VoidCallback
?
onReady
;
final
VoidCallback
?
onDispose
;
final
bool
?
enableLog
;
final
LogWriterCallback
?
logWriterCallback
;
final
bool
?
popGesture
;
final
SmartManagement
smartManagement
;
final
Bindings
?
initialBinding
;
final
Duration
?
transitionDuration
;
final
bool
?
defaultGlobalState
;
final
List
<
GetPage
>?
getPages
;
final
GetPage
?
unknownRoute
;
final
RouteInformationProvider
?
routeInformationProvider
;
final
RouteInformationParser
<
Object
>?
routeInformationParser
;
final
RouterDelegate
<
Object
>?
routerDelegate
;
final
BackButtonDispatcher
?
backButtonDispatcher
;
const
GetMaterialApp
({
Key
?
key
,
this
.
navigatorKey
,
...
...
@@ -72,63 +129,6 @@ class GetMaterialApp extends StatelessWidget {
backButtonDispatcher
=
null
,
super
(
key:
key
);
final
GlobalKey
<
NavigatorState
>?
navigatorKey
;
final
GlobalKey
<
ScaffoldMessengerState
>?
scaffoldMessengerKey
;
final
Widget
?
home
;
final
Map
<
String
,
WidgetBuilder
>?
routes
;
final
String
?
initialRoute
;
final
RouteFactory
?
onGenerateRoute
;
final
InitialRouteListFactory
?
onGenerateInitialRoutes
;
final
RouteFactory
?
onUnknownRoute
;
final
List
<
NavigatorObserver
>?
navigatorObservers
;
final
TransitionBuilder
?
builder
;
final
String
title
;
final
GenerateAppTitle
?
onGenerateTitle
;
final
ThemeData
?
theme
;
final
ThemeData
?
darkTheme
;
final
ThemeMode
themeMode
;
final
CustomTransition
?
customTransition
;
final
Color
?
color
;
final
Map
<
String
,
Map
<
String
,
String
>>?
translationsKeys
;
final
Translations
?
translations
;
final
TextDirection
?
textDirection
;
final
Locale
?
locale
;
final
Locale
?
fallbackLocale
;
final
Iterable
<
LocalizationsDelegate
<
dynamic
>>?
localizationsDelegates
;
final
LocaleListResolutionCallback
?
localeListResolutionCallback
;
final
LocaleResolutionCallback
?
localeResolutionCallback
;
final
Iterable
<
Locale
>
supportedLocales
;
final
bool
showPerformanceOverlay
;
final
bool
checkerboardRasterCacheImages
;
final
bool
checkerboardOffscreenLayers
;
final
bool
showSemanticsDebugger
;
final
bool
debugShowCheckedModeBanner
;
final
Map
<
LogicalKeySet
,
Intent
>?
shortcuts
;
final
ScrollBehavior
?
scrollBehavior
;
final
ThemeData
?
highContrastTheme
;
final
ThemeData
?
highContrastDarkTheme
;
final
Map
<
Type
,
Action
<
Intent
>>?
actions
;
final
bool
debugShowMaterialGrid
;
final
ValueChanged
<
Routing
?>?
routingCallback
;
final
Transition
?
defaultTransition
;
final
bool
?
opaqueRoute
;
final
VoidCallback
?
onInit
;
final
VoidCallback
?
onReady
;
final
VoidCallback
?
onDispose
;
final
bool
?
enableLog
;
final
LogWriterCallback
?
logWriterCallback
;
final
bool
?
popGesture
;
final
SmartManagement
smartManagement
;
final
Bindings
?
initialBinding
;
final
Duration
?
transitionDuration
;
final
bool
?
defaultGlobalState
;
final
List
<
GetPage
>?
getPages
;
final
GetPage
?
unknownRoute
;
final
RouteInformationProvider
?
routeInformationProvider
;
final
RouteInformationParser
<
Object
>?
routeInformationParser
;
final
RouterDelegate
<
Object
>?
routerDelegate
;
final
BackButtonDispatcher
?
backButtonDispatcher
;
GetMaterialApp
.
router
({
Key
?
key
,
this
.
routeInformationProvider
,
...
...
@@ -200,31 +200,6 @@ class GetMaterialApp extends StatelessWidget {
Get
.
routeInformationParser
=
routeInformationParser
;
}
Route
<
dynamic
>
generator
(
RouteSettings
settings
)
{
return
PageRedirect
(
settings:
settings
,
unknownRoute:
unknownRoute
).
page
();
}
List
<
Route
<
dynamic
>>
initialRoutesGenerate
(
String
name
)
{
return
[
PageRedirect
(
settings:
RouteSettings
(
name:
name
),
unknownRoute:
unknownRoute
,
).
page
()
];
}
Widget
defaultBuilder
(
BuildContext
context
,
Widget
?
child
)
{
return
Directionality
(
textDirection:
textDirection
??
(
rtlLanguages
.
contains
(
Get
.
locale
?.
languageCode
)
?
TextDirection
.
rtl
:
TextDirection
.
ltr
),
child:
builder
==
null
?
(
child
??
Material
())
:
builder
!(
context
,
child
??
Material
()),
);
}
@override
Widget
build
(
BuildContext
context
)
=>
GetBuilder
<
GetMaterialController
>(
init:
Get
.
rootController
,
...
...
@@ -270,7 +245,6 @@ class GetMaterialApp extends StatelessWidget {
?
MaterialApp
.
router
(
routerDelegate:
routerDelegate
!,
routeInformationParser:
routeInformationParser
!,
scaffoldMessengerKey:
scaffoldMessengerKey
,
backButtonDispatcher:
backButtonDispatcher
,
routeInformationProvider:
routeInformationProvider
,
key:
_
.
unikey
,
...
...
@@ -283,6 +257,8 @@ class GetMaterialApp extends StatelessWidget {
_
.
darkTheme
??
darkTheme
??
theme
??
ThemeData
.
fallback
(),
themeMode:
_
.
themeMode
??
themeMode
,
locale:
Get
.
locale
??
locale
,
scaffoldMessengerKey:
scaffoldMessengerKey
??
_
.
scaffoldMessengerKey
,
localizationsDelegates:
localizationsDelegates
,
localeListResolutionCallback:
localeListResolutionCallback
,
localeResolutionCallback:
localeResolutionCallback
,
...
...
@@ -301,7 +277,8 @@ class GetMaterialApp extends StatelessWidget {
navigatorKey:
(
navigatorKey
==
null
?
Get
.
key
:
Get
.
addKey
(
navigatorKey
!)),
scaffoldMessengerKey:
scaffoldMessengerKey
,
scaffoldMessengerKey:
scaffoldMessengerKey
??
_
.
scaffoldMessengerKey
,
home:
home
,
routes:
routes
??
const
<
String
,
WidgetBuilder
>{},
initialRoute:
initialRoute
,
...
...
@@ -343,4 +320,29 @@ class GetMaterialApp extends StatelessWidget {
// actions: actions,
),
);
Widget
defaultBuilder
(
BuildContext
context
,
Widget
?
child
)
{
return
Directionality
(
textDirection:
textDirection
??
(
rtlLanguages
.
contains
(
Get
.
locale
?.
languageCode
)
?
TextDirection
.
rtl
:
TextDirection
.
ltr
),
child:
builder
==
null
?
(
child
??
Material
())
:
builder
!(
context
,
child
??
Material
()),
);
}
Route
<
dynamic
>
generator
(
RouteSettings
settings
)
{
return
PageRedirect
(
settings:
settings
,
unknownRoute:
unknownRoute
).
page
();
}
List
<
Route
<
dynamic
>>
initialRoutesGenerate
(
String
name
)
{
return
[
PageRedirect
(
settings:
RouteSettings
(
name:
name
),
unknownRoute:
unknownRoute
,
).
page
()
];
}
}
...
...
lib/get_navigation/src/root/root_controller.dart
View file @
955c18d
import
'package:flutter/material.dart'
;
import
'../../../get_state_manager/get_state_manager.dart'
;
import
'../../../get_utils/get_utils.dart'
;
import
'../routes/custom_transition.dart'
;
...
...
@@ -12,6 +13,8 @@ class GetMaterialController extends GetxController {
ThemeData
?
darkTheme
;
ThemeMode
?
themeMode
;
final
scaffoldMessengerKey
=
GlobalKey
<
ScaffoldMessengerState
>();
bool
defaultPopGesture
=
GetPlatform
.
isIOS
;
bool
defaultOpaqueRoute
=
true
;
...
...
@@ -31,6 +34,8 @@ class GetMaterialController extends GetxController {
var
_key
=
GlobalKey
<
NavigatorState
>(
debugLabel:
'Key Created by default'
);
Map
<
dynamic
,
GlobalKey
<
NavigatorState
>>
keys
=
{};
GlobalKey
<
NavigatorState
>
get
key
=>
_key
;
GlobalKey
<
NavigatorState
>?
addKey
(
GlobalKey
<
NavigatorState
>
newKey
)
{
...
...
@@ -38,7 +43,10 @@ class GetMaterialController extends GetxController {
return
key
;
}
Map
<
dynamic
,
GlobalKey
<
NavigatorState
>>
keys
=
{};
void
restartApp
()
{
unikey
=
UniqueKey
();
update
();
}
void
setTheme
(
ThemeData
value
)
{
if
(
darkTheme
==
null
)
{
...
...
@@ -57,9 +65,4 @@ class GetMaterialController extends GetxController {
themeMode
=
value
;
update
();
}
void
restartApp
()
{
unikey
=
UniqueKey
();
update
();
}
}
...
...
lib/get_navigation/src/routes/observers/route_observer.dart
View file @
955c18d
...
...
@@ -5,37 +5,8 @@ import '../../../../instance_manager.dart';
import
'../../../get_navigation.dart'
;
import
'../../dialog/dialog_route.dart'
;
import
'../../router_report.dart'
;
import
'../../snackbar/snack_route.dart'
;
import
'../default_route.dart'
;
class
Routing
{
String
current
;
String
previous
;
dynamic
args
;
String
removed
;
Route
<
dynamic
>?
route
;
bool
?
isBack
;
bool
?
isSnackbar
;
bool
?
isBottomSheet
;
bool
?
isDialog
;
Routing
({
this
.
current
=
''
,
this
.
previous
=
''
,
this
.
args
,
this
.
removed
=
''
,
this
.
route
,
this
.
isBack
,
this
.
isSnackbar
,
this
.
isBottomSheet
,
this
.
isDialog
,
});
void
update
(
void
fn
(
Routing
value
))
{
fn
(
this
);
}
}
/// Extracts the name of a route based on it's instance type
/// or null if not possible.
String
?
_extractRouteName
(
Route
?
route
)
{
...
...
@@ -58,49 +29,70 @@ String? _extractRouteName(Route? route) {
return
null
;
}
/// This is basically a util for rules about 'what a route is'
class
_RouteData
{
final
bool
isGetPageRoute
;
final
bool
isSnackbar
;
final
bool
isBottomSheet
;
final
bool
isDialog
;
final
String
?
name
;
_RouteData
({
required
this
.
name
,
required
this
.
isGetPageRoute
,
required
this
.
isSnackbar
,
required
this
.
isBottomSheet
,
required
this
.
isDialog
,
});
factory
_RouteData
.
ofRoute
(
Route
?
route
)
{
return
_RouteData
(
name:
_extractRouteName
(
route
),
isGetPageRoute:
route
is
GetPageRoute
,
isSnackbar:
route
is
SnackRoute
,
isDialog:
route
is
GetDialogRoute
,
isBottomSheet:
route
is
GetModalBottomSheetRoute
,
);
}
}
class
GetObserver
extends
NavigatorObserver
{
final
Function
(
Routing
?)?
routing
;
final
Routing
?
_routeSend
;
GetObserver
([
this
.
routing
,
this
.
_routeSend
]);
final
Routing
?
_routeSend
;
@override
void
didPop
(
Route
route
,
Route
?
previousRoute
)
{
super
.
didPop
(
route
,
previousRoute
);
final
currentRoute
=
_RouteData
.
ofRoute
(
route
);
final
newRoute
=
_RouteData
.
ofRoute
(
previousRoute
);
// if (currentRoute.isSnackbar) {
// // Get.log("CLOSE SNACKBAR ${currentRoute.name}");
// Get.log("CLOSE SNACKBAR");
// } else
if
(
currentRoute
.
isBottomSheet
||
currentRoute
.
isDialog
)
{
Get
.
log
(
"CLOSE
${currentRoute.name}
"
);
}
else
if
(
currentRoute
.
isGetPageRoute
)
{
Get
.
log
(
"CLOSE TO ROUTE
${currentRoute.name}
"
);
}
if
(
previousRoute
!=
null
)
{
RouterReportManager
.
reportCurrentRoute
(
previousRoute
);
}
// Here we use a 'inverse didPush set', meaning that we use
// previous route instead of 'route' because this is
// a 'inverse push'
_routeSend
?.
update
((
value
)
{
// Only PageRoute is allowed to change current value
if
(
previousRoute
is
PageRoute
)
{
value
.
current
=
_extractRouteName
(
previousRoute
)
??
''
;
value
.
previous
=
newRoute
.
name
??
''
;
}
else
if
(
value
.
previous
.
isNotEmpty
)
{
value
.
current
=
value
.
previous
;
}
value
.
args
=
previousRoute
?.
settings
.
arguments
;
value
.
route
=
previousRoute
;
value
.
isBack
=
true
;
value
.
removed
=
''
;
// value.isSnackbar = newRoute.isSnackbar;
value
.
isBottomSheet
=
newRoute
.
isBottomSheet
;
value
.
isDialog
=
newRoute
.
isDialog
;
});
// print('currentRoute.isDialog ${currentRoute.isDialog}');
routing
?.
call
(
_routeSend
);
}
@override
void
didPush
(
Route
route
,
Route
?
previousRoute
)
{
super
.
didPush
(
route
,
previousRoute
);
final
newRoute
=
_RouteData
.
ofRoute
(
route
);
if
(
newRoute
.
isSnackbar
)
{
// Get.log("OPEN SNACKBAR ${newRoute.name}");
Get
.
log
(
"OPEN SNACKBAR"
);
}
else
if
(
newRoute
.
isBottomSheet
||
newRoute
.
isDialog
)
{
// if (newRoute.isSnackbar) {
// // Get.log("OPEN SNACKBAR ${newRoute.name}");
// Get.log("OPEN SNACKBAR");
// } else
if
(
newRoute
.
isBottomSheet
||
newRoute
.
isDialog
)
{
Get
.
log
(
"OPEN
${newRoute.name}
"
);
}
else
if
(
newRoute
.
isGetPageRoute
)
{
Get
.
log
(
"GOING TO ROUTE
${newRoute.name}
"
);
...
...
@@ -121,7 +113,7 @@ class GetObserver extends NavigatorObserver {
value
.
route
=
route
;
value
.
isBack
=
false
;
value
.
removed
=
''
;
value
.
isSnackbar
=
newRoute
.
isSnackbar
?
true
:
value
.
isSnackbar
??
false
;
//
value.isSnackbar = newRoute.isSnackbar ? true : value.isSnackbar ?? false;
value
.
isBottomSheet
=
newRoute
.
isBottomSheet
?
true
:
value
.
isBottomSheet
??
false
;
value
.
isDialog
=
newRoute
.
isDialog
?
true
:
value
.
isDialog
??
false
;
...
...
@@ -133,46 +125,27 @@ class GetObserver extends NavigatorObserver {
}
@override
void
didPop
(
Route
route
,
Route
?
previousRoute
)
{
super
.
didPop
(
route
,
previousRoute
);
void
didRemove
(
Route
route
,
Route
?
previousRoute
)
{
super
.
didRemove
(
route
,
previousRoute
);
final
routeName
=
_extractRouteName
(
route
);
final
currentRoute
=
_RouteData
.
ofRoute
(
route
);
final
newRoute
=
_RouteData
.
ofRoute
(
previousRoute
);
if
(
currentRoute
.
isSnackbar
)
{
// Get.log("CLOSE SNACKBAR ${currentRoute.name}");
Get
.
log
(
"CLOSE SNACKBAR"
);
}
else
if
(
currentRoute
.
isBottomSheet
||
currentRoute
.
isDialog
)
{
Get
.
log
(
"CLOSE
${currentRoute.name}
"
);
}
else
if
(
currentRoute
.
isGetPageRoute
)
{
Get
.
log
(
"CLOSE TO ROUTE
${currentRoute.name}
"
);
}
if
(
previousRoute
!=
null
)
{
RouterReportManager
.
reportCurrentRoute
(
previousRoute
);
}
Get
.
log
(
"REMOVING ROUTE
$routeName
"
);
// Here we use a 'inverse didPush set', meaning that we use
// previous route instead of 'route' because this is
// a 'inverse push'
_routeSend
?.
update
((
value
)
{
// Only PageRoute is allowed to change current value
if
(
previousRoute
is
PageRoute
)
{
value
.
current
=
_extractRouteName
(
previousRoute
)
??
''
;
value
.
previous
=
newRoute
.
name
??
''
;
}
else
if
(
value
.
previous
.
isNotEmpty
)
{
value
.
current
=
value
.
previous
;
}
value
.
args
=
previousRoute
?.
settings
.
arguments
;
value
.
route
=
previousRoute
;
value
.
isBack
=
true
;
value
.
removed
=
''
;
value
.
isSnackbar
=
newRoute
.
isSnackbar
;
value
.
isBottomSheet
=
newRoute
.
isBottomSheet
;
value
.
isDialog
=
newRoute
.
isDialog
;
value
.
isBack
=
false
;
value
.
removed
=
routeName
??
''
;
value
.
previous
=
routeName
??
''
;
// value.isSnackbar = currentRoute.isSnackbar ? false : value.isSnackbar;
value
.
isBottomSheet
=
currentRoute
.
isBottomSheet
?
false
:
value
.
isBottomSheet
;
value
.
isDialog
=
currentRoute
.
isDialog
?
false
:
value
.
isDialog
;
});
// print('currentRoute.isDialog ${currentRoute.isDialog}');
if
(
route
is
GetPageRoute
)
{
RouterReportManager
.
reportRouteWillDispose
(
route
);
}
routing
?.
call
(
_routeSend
);
}
...
...
@@ -201,7 +174,7 @@ class GetObserver extends NavigatorObserver {
value
.
isBack
=
false
;
value
.
removed
=
''
;
value
.
previous
=
'
$oldName
'
;
value
.
isSnackbar
=
currentRoute
.
isSnackbar
?
false
:
value
.
isSnackbar
;
//
value.isSnackbar = currentRoute.isSnackbar ? false : value.isSnackbar;
value
.
isBottomSheet
=
currentRoute
.
isBottomSheet
?
false
:
value
.
isBottomSheet
;
value
.
isDialog
=
currentRoute
.
isDialog
?
false
:
value
.
isDialog
;
...
...
@@ -212,29 +185,59 @@ class GetObserver extends NavigatorObserver {
routing
?.
call
(
_routeSend
);
}
}
@override
void
didRemove
(
Route
route
,
Route
?
previousRoute
)
{
super
.
didRemove
(
route
,
previousRoute
);
final
routeName
=
_extractRouteName
(
route
);
final
currentRoute
=
_RouteData
.
ofRoute
(
route
);
class
Routing
{
String
current
;
String
previous
;
dynamic
args
;
String
removed
;
Route
<
dynamic
>?
route
;
bool
?
isBack
;
// bool? isSnackbar;
bool
?
isBottomSheet
;
bool
?
isDialog
;
Get
.
log
(
"REMOVING ROUTE
$routeName
"
);
Routing
({
this
.
current
=
''
,
this
.
previous
=
''
,
this
.
args
,
this
.
removed
=
''
,
this
.
route
,
this
.
isBack
,
// this.isSnackbar,
this
.
isBottomSheet
,
this
.
isDialog
,
});
_routeSend
?.
update
((
value
)
{
value
.
route
=
previousRoute
;
value
.
isBack
=
false
;
value
.
removed
=
routeName
??
''
;
value
.
previous
=
routeName
??
''
;
value
.
isSnackbar
=
currentRoute
.
isSnackbar
?
false
:
value
.
isSnackbar
;
value
.
isBottomSheet
=
currentRoute
.
isBottomSheet
?
false
:
value
.
isBottomSheet
;
value
.
isDialog
=
currentRoute
.
isDialog
?
false
:
value
.
isDialog
;
});
void
update
(
void
fn
(
Routing
value
))
{
fn
(
this
);
}
}
if
(
route
is
GetPageRoute
)
{
RouterReportManager
.
reportRouteWillDispose
(
route
);
}
routing
?.
call
(
_routeSend
);
/// This is basically a util for rules about 'what a route is'
class
_RouteData
{
final
bool
isGetPageRoute
;
//final bool isSnackbar;
final
bool
isBottomSheet
;
final
bool
isDialog
;
final
String
?
name
;
_RouteData
({
required
this
.
name
,
required
this
.
isGetPageRoute
,
// required this.isSnackbar,
required
this
.
isBottomSheet
,
required
this
.
isDialog
,
});
factory
_RouteData
.
ofRoute
(
Route
?
route
)
{
return
_RouteData
(
name:
_extractRouteName
(
route
),
isGetPageRoute:
route
is
GetPageRoute
,
// isSnackbar: route is SnackRoute,
isDialog:
route
is
GetDialogRoute
,
isBottomSheet:
route
is
GetModalBottomSheetRoute
,
);
}
}
...
...
lib/get_navigation/src/snackbar/snack.dart
View file @
955c18d
import
'dart:async'
;
import
'dart:ui'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/scheduler.dart'
;
import
'../../../get_core/get_core.dart'
;
import
'../../get_navigation.dart'
;
typedef
SnackbarStatusCallback
=
void
Function
(
SnackbarStatus
?
status
);
typedef
OnTap
=
void
Function
(
GetBar
snack
);
typedef
SnackbarStatusCallback
=
void
Function
(
SnackbarStatus
?
status
);
class
GetBar
<
T
extends
Object
>
extends
StatefulWidget
{
GetBar
({
Key
?
key
,
this
.
title
,
this
.
message
,
this
.
titleText
,
this
.
messageText
,
this
.
icon
,
this
.
shouldIconPulse
=
true
,
this
.
maxWidth
,
this
.
margin
=
const
EdgeInsets
.
all
(
0.0
),
this
.
padding
=
const
EdgeInsets
.
all
(
16
),
this
.
borderRadius
=
0.0
,
this
.
borderColor
,
this
.
borderWidth
=
1.0
,
this
.
backgroundColor
=
const
Color
(
0xFF303030
),
this
.
leftBarIndicatorColor
,
this
.
boxShadows
,
this
.
backgroundGradient
,
this
.
mainButton
,
this
.
onTap
,
this
.
duration
,
this
.
isDismissible
=
true
,
this
.
dismissDirection
=
SnackDismissDirection
.
VERTICAL
,
this
.
showProgressIndicator
=
false
,
this
.
progressIndicatorController
,
this
.
progressIndicatorBackgroundColor
,
this
.
progressIndicatorValueColor
,
this
.
snackPosition
=
SnackPosition
.
BOTTOM
,
this
.
snackStyle
=
SnackStyle
.
FLOATING
,
this
.
forwardAnimationCurve
=
Curves
.
easeOutCirc
,
this
.
reverseAnimationCurve
=
Curves
.
easeOutCirc
,
this
.
animationDuration
=
const
Duration
(
seconds:
1
),
this
.
barBlur
=
0.0
,
this
.
overlayBlur
=
0.0
,
this
.
overlayColor
=
Colors
.
transparent
,
this
.
userInputForm
,
SnackbarStatusCallback
?
snackbarStatus
,
})
:
snackbarStatus
=
(
snackbarStatus
??
(
status
)
{}),
super
(
key:
key
);
/// A callback for you to listen to the different Snack status
final
SnackbarStatusCallback
snackbarStatus
;
final
SnackbarStatusCallback
?
snackbarStatus
;
/// The title displayed to the user
final
String
?
title
;
...
...
@@ -192,18 +154,78 @@ class GetBar<T extends Object> extends StatefulWidget {
/// Every other widget is ignored if this is not null.
final
Form
?
userInputForm
;
/// Show the snack. It's call [SnackbarStatus.OPENING] state
/// followed by [SnackbarStatus.OPEN]
Future
<
T
?>?
show
<
T
>()
async
{
return
Get
.
showSnackbar
(
this
);
}
const
GetBar
({
Key
?
key
,
this
.
title
,
this
.
message
,
this
.
titleText
,
this
.
messageText
,
this
.
icon
,
this
.
shouldIconPulse
=
true
,
this
.
maxWidth
,
this
.
margin
=
const
EdgeInsets
.
all
(
0.0
),
this
.
padding
=
const
EdgeInsets
.
all
(
16
),
this
.
borderRadius
=
0.0
,
this
.
borderColor
,
this
.
borderWidth
=
1.0
,
this
.
backgroundColor
=
const
Color
(
0xFF303030
),
this
.
leftBarIndicatorColor
,
this
.
boxShadows
,
this
.
backgroundGradient
,
this
.
mainButton
,
this
.
onTap
,
this
.
duration
,
this
.
isDismissible
=
true
,
this
.
dismissDirection
=
SnackDismissDirection
.
VERTICAL
,
this
.
showProgressIndicator
=
false
,
this
.
progressIndicatorController
,
this
.
progressIndicatorBackgroundColor
,
this
.
progressIndicatorValueColor
,
this
.
snackPosition
=
SnackPosition
.
BOTTOM
,
this
.
snackStyle
=
SnackStyle
.
FLOATING
,
this
.
forwardAnimationCurve
=
Curves
.
easeOutCirc
,
this
.
reverseAnimationCurve
=
Curves
.
easeOutCirc
,
this
.
animationDuration
=
const
Duration
(
seconds:
1
),
this
.
barBlur
=
0.0
,
this
.
overlayBlur
=
0.0
,
this
.
overlayColor
=
Colors
.
transparent
,
this
.
userInputForm
,
this
.
snackbarStatus
,
})
:
super
(
key:
key
);
@override
State
createState
()
{
return
_GetBarState
<
T
>();
}
/// Show the snack. It's call [SnackbarStatus.OPENING] state
/// followed by [SnackbarStatus.OPEN]
Future
<
void
>
show
<
T
>()
async
{
return
Get
.
showSnackbar
(
this
);
}
}
/// Indicates Status of snackbar
/// [SnackbarStatus.OPEN] Snack is fully open, [SnackbarStatus.CLOSED] Snackbar
/// has closed,
/// [SnackbarStatus.OPENING] Starts with the opening animation and ends
/// with the full
/// snackbar display, [SnackbarStatus.CLOSING] Starts with the closing animation
/// and ends
/// with the full snackbar dispose
enum
SnackbarStatus
{
OPEN
,
CLOSED
,
OPENING
,
CLOSING
}
/// Indicates the direction in which it is possible to dismiss
/// If vertical, dismiss up will be allowed if [SnackPosition.TOP]
/// If vertical, dismiss down will be allowed if [SnackPosition.BOTTOM]
enum
SnackDismissDirection
{
HORIZONTAL
,
VERTICAL
}
/// Indicates if snack is going to start at the [TOP] or at the [BOTTOM]
enum
SnackPosition
{
TOP
,
BOTTOM
}
/// Indicates if snack will be attached to the edge of the screen or not
enum
SnackStyle
{
FLOATING
,
GROUNDED
}
class
_GetBarState
<
K
extends
Object
>
extends
State
<
GetBar
>
with
TickerProviderStateMixin
{
SnackbarStatus
?
currentStatus
;
...
...
@@ -223,6 +245,49 @@ class _GetBarState<K extends Object> extends State<GetBar>
FocusScopeNode
?
_focusNode
;
late
FocusAttachment
_focusAttachment
;
final
Completer
<
Size
>
_boxHeightCompleter
=
Completer
<
Size
>();
late
VoidCallback
_progressListener
;
late
CurvedAnimation
_progressAnimation
;
GlobalKey
backgroundBoxKey
=
GlobalKey
();
@override
Widget
build
(
BuildContext
context
)
{
return
Align
(
heightFactor:
1.0
,
child:
Material
(
color:
widget
.
snackStyle
==
SnackStyle
.
FLOATING
?
Colors
.
transparent
:
widget
.
backgroundColor
,
child:
SafeArea
(
minimum:
widget
.
snackPosition
==
SnackPosition
.
BOTTOM
?
EdgeInsets
.
only
(
bottom:
MediaQuery
.
of
(
context
).
viewInsets
.
bottom
)
:
EdgeInsets
.
only
(
top:
MediaQuery
.
of
(
context
).
padding
.
top
),
bottom:
widget
.
snackPosition
==
SnackPosition
.
BOTTOM
,
top:
widget
.
snackPosition
==
SnackPosition
.
TOP
,
left:
false
,
right:
false
,
child:
_getSnack
(),
),
),
);
}
@override
void
dispose
()
{
_fadeController
?.
dispose
();
widget
.
progressIndicatorController
?.
removeListener
(
_progressListener
);
widget
.
progressIndicatorController
?.
dispose
();
_focusAttachment
.
detach
();
_focusNode
!.
dispose
();
super
.
dispose
();
}
@override
void
initState
()
{
super
.
initState
();
...
...
@@ -250,20 +315,27 @@ Set either a message or messageText""");
_focusAttachment
=
_focusNode
!.
attach
(
context
);
}
@override
void
dispose
()
{
_fadeController
?.
dispose
();
widget
.
progressIndicatorController
?.
removeListener
(
_progressListener
);
widget
.
progressIndicatorController
?.
dispose
();
_focusAttachment
.
detach
();
_focusNode
!.
dispose
();
super
.
dispose
();
Widget
_buildLeftBarIndicator
()
{
if
(
widget
.
leftBarIndicatorColor
!=
null
)
{
return
FutureBuilder
<
Size
>(
future:
_boxHeightCompleter
.
future
,
builder:
(
buildContext
,
snapshot
)
{
if
(
snapshot
.
hasData
)
{
return
Container
(
color:
widget
.
leftBarIndicatorColor
,
width:
5.0
,
height:
snapshot
.
data
!.
height
,
);
}
else
{
return
_emptyWidget
;
}
},
);
}
else
{
return
_emptyWidget
;
}
}
final
Completer
<
Size
>
_boxHeightCompleter
=
Completer
<
Size
>();
void
_configureLeftBarFuture
()
{
SchedulerBinding
.
instance
!.
addPostFrameCallback
(
(
_
)
{
...
...
@@ -277,6 +349,19 @@ Set either a message or messageText""");
);
}
void
_configureProgressIndicatorAnimation
()
{
if
(
widget
.
showProgressIndicator
&&
widget
.
progressIndicatorController
!=
null
)
{
_progressListener
=
()
{
setState
(()
{});
};
widget
.
progressIndicatorController
!.
addListener
(
_progressListener
);
_progressAnimation
=
CurvedAnimation
(
curve:
Curves
.
linear
,
parent:
widget
.
progressIndicatorController
!);
}
}
void
_configurePulseAnimation
()
{
_fadeController
=
AnimationController
(
vsync:
this
,
duration:
_pulseAnimationDuration
);
...
...
@@ -299,92 +384,6 @@ Set either a message or messageText""");
_fadeController
!.
forward
();
}
late
VoidCallback
_progressListener
;
void
_configureProgressIndicatorAnimation
()
{
if
(
widget
.
showProgressIndicator
&&
widget
.
progressIndicatorController
!=
null
)
{
_progressListener
=
()
{
setState
(()
{});
};
widget
.
progressIndicatorController
!.
addListener
(
_progressListener
);
_progressAnimation
=
CurvedAnimation
(
curve:
Curves
.
linear
,
parent:
widget
.
progressIndicatorController
!);
}
}
@override
Widget
build
(
BuildContext
context
)
{
return
Align
(
heightFactor:
1.0
,
child:
Material
(
color:
widget
.
snackStyle
==
SnackStyle
.
FLOATING
?
Colors
.
transparent
:
widget
.
backgroundColor
,
child:
SafeArea
(
minimum:
widget
.
snackPosition
==
SnackPosition
.
BOTTOM
?
EdgeInsets
.
only
(
// bottom: (GetUtils.isGreaterThan(
// MediaQuery.of(context).viewInsets.bottom,
// MediaQuery.of(context).padding.bottom)
// ? MediaQuery.of(context).viewInsets.bottom
// : MediaQuery.of(context).padding.bottom))
bottom:
MediaQuery
.
of
(
context
).
viewInsets
.
bottom
)
:
EdgeInsets
.
only
(
top:
MediaQuery
.
of
(
context
).
padding
.
top
),
bottom:
widget
.
snackPosition
==
SnackPosition
.
BOTTOM
,
top:
widget
.
snackPosition
==
SnackPosition
.
TOP
,
left:
false
,
right:
false
,
child:
_getSnack
(),
),
),
);
}
Widget
_getSnack
()
{
Widget
snack
;
if
(
widget
.
userInputForm
!=
null
)
{
snack
=
_generateInputSnack
();
}
else
{
snack
=
_generateSnack
();
}
return
Stack
(
children:
[
FutureBuilder
<
Size
>(
future:
_boxHeightCompleter
.
future
,
builder:
(
context
,
snapshot
)
{
if
(
snapshot
.
hasData
)
{
if
(
widget
.
barBlur
==
0
)
{
return
_emptyWidget
;
}
return
ClipRRect
(
borderRadius:
BorderRadius
.
circular
(
widget
.
borderRadius
),
child:
BackdropFilter
(
filter:
ImageFilter
.
blur
(
sigmaX:
widget
.
barBlur
!,
sigmaY:
widget
.
barBlur
!),
child:
Container
(
height:
snapshot
.
data
!.
height
,
width:
snapshot
.
data
!.
width
,
decoration:
BoxDecoration
(
color:
Colors
.
transparent
,
borderRadius:
BorderRadius
.
circular
(
widget
.
borderRadius
),
),
),
),
);
}
else
{
return
_emptyWidget
;
}
},
),
snack
,
],
);
}
Widget
_generateInputSnack
()
{
return
Container
(
key:
backgroundBoxKey
,
...
...
@@ -412,9 +411,6 @@ Set either a message or messageText""");
);
}
late
CurvedAnimation
_progressAnimation
;
GlobalKey
backgroundBoxKey
=
GlobalKey
();
Widget
_generateSnack
()
{
return
Container
(
key:
backgroundBoxKey
,
...
...
@@ -611,25 +607,11 @@ Set either a message or messageText""");
}
}
Widget
_buildLeftBarIndicator
()
{
if
(
widget
.
leftBarIndicatorColor
!=
null
)
{
return
FutureBuilder
<
Size
>(
future:
_boxHeightCompleter
.
future
,
builder:
(
buildContext
,
snapshot
)
{
if
(
snapshot
.
hasData
)
{
return
Container
(
color:
widget
.
leftBarIndicatorColor
,
width:
5.0
,
height:
snapshot
.
data
!.
height
,
);
}
else
{
return
_emptyWidget
;
}
},
);
}
else
{
return
_emptyWidget
;
}
Text
_getDefaultNotificationText
()
{
return
Text
(
widget
.
message
??
""
,
style:
TextStyle
(
fontSize:
14.0
,
color:
Colors
.
white
),
);
}
Widget
?
_getIcon
()
{
...
...
@@ -645,6 +627,53 @@ Set either a message or messageText""");
}
}
Widget
?
_getMainActionButton
()
{
return
widget
.
mainButton
;
}
Widget
_getSnack
()
{
Widget
snack
;
if
(
widget
.
userInputForm
!=
null
)
{
snack
=
_generateInputSnack
();
}
else
{
snack
=
_generateSnack
();
}
return
Stack
(
children:
[
FutureBuilder
<
Size
>(
future:
_boxHeightCompleter
.
future
,
builder:
(
context
,
snapshot
)
{
if
(
snapshot
.
hasData
)
{
if
(
widget
.
barBlur
==
0
)
{
return
_emptyWidget
;
}
return
ClipRRect
(
borderRadius:
BorderRadius
.
circular
(
widget
.
borderRadius
),
child:
BackdropFilter
(
filter:
ImageFilter
.
blur
(
sigmaX:
widget
.
barBlur
!,
sigmaY:
widget
.
barBlur
!),
child:
Container
(
height:
snapshot
.
data
!.
height
,
width:
snapshot
.
data
!.
width
,
decoration:
BoxDecoration
(
color:
Colors
.
transparent
,
borderRadius:
BorderRadius
.
circular
(
widget
.
borderRadius
),
),
),
),
);
}
else
{
return
_emptyWidget
;
}
},
),
snack
,
],
);
}
Widget
_getTitleText
()
{
return
widget
.
titleText
??
Text
(
...
...
@@ -653,36 +682,4 @@ Set either a message or messageText""");
fontSize:
16.0
,
color:
Colors
.
white
,
fontWeight:
FontWeight
.
bold
),
);
}
Text
_getDefaultNotificationText
()
{
return
Text
(
widget
.
message
??
""
,
style:
TextStyle
(
fontSize:
14.0
,
color:
Colors
.
white
),
);
}
Widget
?
_getMainActionButton
()
{
return
widget
.
mainButton
;
}
}
/// Indicates if snack is going to start at the [TOP] or at the [BOTTOM]
enum
SnackPosition
{
TOP
,
BOTTOM
}
/// Indicates if snack will be attached to the edge of the screen or not
enum
SnackStyle
{
FLOATING
,
GROUNDED
}
/// Indicates the direction in which it is possible to dismiss
/// If vertical, dismiss up will be allowed if [SnackPosition.TOP]
/// If vertical, dismiss down will be allowed if [SnackPosition.BOTTOM]
enum
SnackDismissDirection
{
HORIZONTAL
,
VERTICAL
}
/// Indicates Status of snackbar
/// [SnackbarStatus.OPEN] Snack is fully open, [SnackbarStatus.CLOSED] Snackbar
/// has closed,
/// [SnackbarStatus.OPENING] Starts with the opening animation and ends
/// with the full
/// snackbar display, [SnackbarStatus.CLOSING] Starts with the closing animation
/// and ends
/// with the full snackbar dispose
enum
SnackbarStatus
{
OPEN
,
CLOSED
,
OPENING
,
CLOSING
}
...
...
lib/get_navigation/src/snackbar/snack_route.dart
deleted
100644 → 0
View file @
e7c2916
import
'dart:async'
;
import
'dart:ui'
;
import
'package:flutter/widgets.dart'
;
import
'../../../get_core/get_core.dart'
;
import
'../../get_navigation.dart'
;
import
'snack.dart'
;
class
SnackRoute
<
T
>
extends
OverlayRoute
<
T
>
{
late
Animation
<
double
>
_filterBlurAnimation
;
late
Animation
<
Color
?>
_filterColorAnimation
;
SnackRoute
({
required
this
.
snack
,
RouteSettings
?
settings
,
})
:
super
(
settings:
settings
)
{
_builder
=
Builder
(
builder:
(
_
)
{
return
GestureDetector
(
child:
snack
,
onTap:
snack
.
onTap
!=
null
?
()
=>
snack
.
onTap
!(
snack
)
:
null
,
);
});
_configureAlignment
(
snack
.
snackPosition
);
_snackbarStatus
=
snack
.
snackbarStatus
;
}
_configureAlignment
(
SnackPosition
snackPosition
)
{
switch
(
snack
.
snackPosition
)
{
case
SnackPosition
.
TOP
:
{
_initialAlignment
=
Alignment
(-
1.0
,
-
2.0
);
_endAlignment
=
Alignment
(-
1.0
,
-
1.0
);
break
;
}
case
SnackPosition
.
BOTTOM
:
{
_initialAlignment
=
Alignment
(-
1.0
,
2.0
);
_endAlignment
=
Alignment
(-
1.0
,
1.0
);
break
;
}
}
}
GetBar
snack
;
Builder
?
_builder
;
final
Completer
<
T
>
_transitionCompleter
=
Completer
<
T
>();
late
SnackbarStatusCallback
_snackbarStatus
;
Alignment
?
_initialAlignment
;
Alignment
?
_endAlignment
;
bool
_wasDismissedBySwipe
=
false
;
bool
_onTappedDismiss
=
false
;
Timer
?
_timer
;
bool
get
opaque
=>
false
;
@override
Iterable
<
OverlayEntry
>
createOverlayEntries
()
{
return
<
OverlayEntry
>[
if
(
snack
.
overlayBlur
>
0.0
)
...[
OverlayEntry
(
builder:
(
context
)
{
return
GestureDetector
(
onTap:
()
{
if
(
snack
.
isDismissible
&&
!
_onTappedDismiss
)
{
_onTappedDismiss
=
true
;
Get
.
back
();
}
},
child:
AnimatedBuilder
(
animation:
_filterBlurAnimation
,
builder:
(
context
,
child
)
{
return
BackdropFilter
(
filter:
ImageFilter
.
blur
(
sigmaX:
_filterBlurAnimation
.
value
,
sigmaY:
_filterBlurAnimation
.
value
),
child:
Container
(
constraints:
BoxConstraints
.
expand
(),
color:
_filterColorAnimation
.
value
,
),
);
},
),
);
},
maintainState:
false
,
opaque:
opaque
,
),
],
OverlayEntry
(
builder:
(
context
)
{
final
Widget
annotatedChild
=
Semantics
(
child:
AlignTransition
(
alignment:
_animation
!,
child:
snack
.
isDismissible
?
_getDismissibleSnack
(
_builder
)
:
_getSnack
(),
),
focused:
false
,
container:
true
,
explicitChildNodes:
true
,
);
return
annotatedChild
;
},
maintainState:
false
,
opaque:
opaque
,
),
];
}
String
dismissibleKeyGen
=
""
;
Widget
_getDismissibleSnack
(
Widget
?
child
)
{
return
Dismissible
(
direction:
_getDismissDirection
(),
resizeDuration:
null
,
confirmDismiss:
(
_
)
{
if
(
currentStatus
==
SnackbarStatus
.
OPENING
||
currentStatus
==
SnackbarStatus
.
CLOSING
)
{
return
Future
.
value
(
false
);
}
return
Future
.
value
(
true
);
},
key:
Key
(
dismissibleKeyGen
),
onDismissed:
(
_
)
{
dismissibleKeyGen
+=
"1"
;
_cancelTimer
();
_wasDismissedBySwipe
=
true
;
if
(
isCurrent
)
{
navigator
!.
pop
();
}
else
{
navigator
!.
removeRoute
(
this
);
}
},
child:
_getSnack
(),
);
}
Widget
_getSnack
()
{
return
Container
(
margin:
snack
.
margin
,
child:
_builder
,
);
}
DismissDirection
_getDismissDirection
()
{
if
(
snack
.
dismissDirection
==
SnackDismissDirection
.
HORIZONTAL
)
{
return
DismissDirection
.
horizontal
;
}
else
{
if
(
snack
.
snackPosition
==
SnackPosition
.
TOP
)
{
return
DismissDirection
.
up
;
}
return
DismissDirection
.
down
;
}
}
@override
bool
get
finishedWhenPopped
=>
_controller
!.
status
==
AnimationStatus
.
dismissed
;
/// The animation that drives the route's transition and the previous route's
/// forward transition.
Animation
<
Alignment
>?
_animation
;
/// The animation controller that the route uses to drive the transitions.
///
/// The animation itself is exposed by the [animation] property.
AnimationController
?
_controller
;
/// Called to create the animation controller that will drive the transitions
/// to this route from the previous one, and back to the previous route
/// from this one.
AnimationController
createAnimationController
()
{
assert
(!
_transitionCompleter
.
isCompleted
,
'Cannot reuse a
$runtimeType
after disposing it.'
);
assert
(
snack
.
animationDuration
>=
Duration
.
zero
);
return
AnimationController
(
duration:
snack
.
animationDuration
,
debugLabel:
debugLabel
,
vsync:
navigator
!,
);
}
/// Called to create the animation that exposes the current progress of
/// the transition controlled by the animation controller created by
/// `createAnimationController()`.
Animation
<
Alignment
>
createAnimation
()
{
assert
(!
_transitionCompleter
.
isCompleted
,
'Cannot reuse a
$runtimeType
after disposing it.'
);
assert
(
_controller
!=
null
);
return
AlignmentTween
(
begin:
_initialAlignment
,
end:
_endAlignment
).
animate
(
CurvedAnimation
(
parent:
_controller
!,
curve:
snack
.
forwardAnimationCurve
,
reverseCurve:
snack
.
reverseAnimationCurve
,
),
);
}
Animation
<
double
>
createBlurFilterAnimation
()
{
return
Tween
(
begin:
0.0
,
end:
snack
.
overlayBlur
).
animate
(
CurvedAnimation
(
parent:
_controller
!,
curve:
Interval
(
0.0
,
0.35
,
curve:
Curves
.
easeInOutCirc
,
),
),
);
}
Animation
<
Color
?>
createColorFilterAnimation
()
{
return
ColorTween
(
begin:
Color
(
0x00000000
),
end:
snack
.
overlayColor
)
.
animate
(
CurvedAnimation
(
parent:
_controller
!,
curve:
Interval
(
0.0
,
0.35
,
curve:
Curves
.
easeInOutCirc
,
),
),
);
}
T
?
_result
;
SnackbarStatus
?
currentStatus
;
void
_handleStatusChanged
(
AnimationStatus
status
)
{
switch
(
status
)
{
case
AnimationStatus
.
completed
:
currentStatus
=
SnackbarStatus
.
OPEN
;
_snackbarStatus
(
currentStatus
);
if
(
overlayEntries
.
isNotEmpty
)
overlayEntries
.
first
.
opaque
=
opaque
;
break
;
case
AnimationStatus
.
forward
:
currentStatus
=
SnackbarStatus
.
OPENING
;
_snackbarStatus
(
currentStatus
);
break
;
case
AnimationStatus
.
reverse
:
currentStatus
=
SnackbarStatus
.
CLOSING
;
_snackbarStatus
(
currentStatus
);
if
(
overlayEntries
.
isNotEmpty
)
overlayEntries
.
first
.
opaque
=
false
;
break
;
case
AnimationStatus
.
dismissed
:
assert
(!
overlayEntries
.
first
.
opaque
);
// We might still be the current route if a subclass is controlling the
// the transition and hits the dismissed status. For example, the iOS
// back gesture drives this animation to the dismissed status before
// popping the navigator.
currentStatus
=
SnackbarStatus
.
CLOSED
;
_snackbarStatus
(
currentStatus
);
if
(!
isCurrent
)
{
navigator
!.
finalizeRoute
(
this
);
// assert(overlayEntries.isEmpty);
}
break
;
}
changedInternalState
();
}
@override
void
install
()
{
assert
(!
_transitionCompleter
.
isCompleted
,
'Cannot install a
$runtimeType
after disposing it.'
);
_controller
=
createAnimationController
();
assert
(
_controller
!=
null
,
'
$runtimeType
.createAnimationController() returned null.'
);
_filterBlurAnimation
=
createBlurFilterAnimation
();
_filterColorAnimation
=
createColorFilterAnimation
();
_animation
=
createAnimation
();
assert
(
_animation
!=
null
,
'
$runtimeType
.createAnimation() returned null.'
);
super
.
install
();
}
@override
TickerFuture
didPush
()
{
super
.
didPush
();
assert
(
_controller
!=
null
,
// ignore: lines_longer_than_80_chars
'
$runtimeType
.didPush called before calling install() or after calling dispose().'
,
);
assert
(
!
_transitionCompleter
.
isCompleted
,
'Cannot reuse a
$runtimeType
after disposing it.'
,
);
_animation
!.
addStatusListener
(
_handleStatusChanged
);
_configureTimer
();
return
_controller
!.
forward
();
}
@override
void
didReplace
(
Route
<
dynamic
>?
oldRoute
)
{
assert
(
_controller
!=
null
,
// ignore: lines_longer_than_80_chars
'
$runtimeType
.didReplace called before calling install() or after calling dispose().'
,
);
assert
(
!
_transitionCompleter
.
isCompleted
,
'Cannot reuse a
$runtimeType
after disposing it.'
,
);
if
(
oldRoute
is
SnackRoute
)
{
_controller
!.
value
=
oldRoute
.
_controller
!.
value
;
}
_animation
!.
addStatusListener
(
_handleStatusChanged
);
super
.
didReplace
(
oldRoute
);
}
@override
bool
didPop
(
T
?
result
)
{
assert
(
_controller
!=
null
,
// ignore: lines_longer_than_80_chars
'
$runtimeType
.didPop called before calling install() or after calling dispose().'
,
);
assert
(
!
_transitionCompleter
.
isCompleted
,
'Cannot reuse a
$runtimeType
after disposing it.'
,
);
_result
=
result
;
_cancelTimer
();
if
(
_wasDismissedBySwipe
)
{
Timer
(
Duration
(
milliseconds:
200
),
()
{
_controller
!.
reset
();
});
_wasDismissedBySwipe
=
false
;
}
else
{
_controller
!.
reverse
();
}
return
super
.
didPop
(
result
);
}
void
_configureTimer
()
{
if
(
snack
.
duration
!=
null
)
{
if
(
_timer
!=
null
&&
_timer
!.
isActive
)
{
_timer
!.
cancel
();
}
_timer
=
Timer
(
snack
.
duration
!,
()
{
if
(
isCurrent
)
{
navigator
!.
pop
();
}
else
if
(
isActive
)
{
navigator
!.
removeRoute
(
this
);
}
});
}
else
{
if
(
_timer
!=
null
)
{
_timer
!.
cancel
();
}
}
}
void
_cancelTimer
()
{
if
(
_timer
!=
null
&&
_timer
!.
isActive
)
{
_timer
!.
cancel
();
}
}
/// Whether this route can perform a transition to the given route.
/// Subclasses can override this method to restrict the set of routes they
/// need to coordinate transitions with.
bool
canTransitionTo
(
SnackRoute
<
dynamic
>
nextRoute
)
=>
true
;
/// Whether this route can perform a transition from the given route.
///
/// Subclasses can override this method to restrict the set of routes they
/// need to coordinate transitions with.
bool
canTransitionFrom
(
SnackRoute
<
dynamic
>
previousRoute
)
=>
true
;
@override
void
dispose
()
{
assert
(!
_transitionCompleter
.
isCompleted
,
'Cannot dispose a
$runtimeType
twice.'
);
_controller
?.
dispose
();
_transitionCompleter
.
complete
(
_result
);
super
.
dispose
();
}
/// A short description of this route useful for debugging.
String
get
debugLabel
=>
'
$runtimeType
'
;
}
lib/get_navigation/src/snackbar/snackbar_controller.dart
0 → 100644
View file @
955c18d
import
'dart:async'
;
import
'dart:ui'
;
import
'package:flutter/material.dart'
;
import
'../../../get.dart'
;
class
SnackbarController
{
late
Animation
<
double
>
_filterBlurAnimation
;
late
Animation
<
Color
?>
_filterColorAnimation
;
final
GetBar
<
Object
>
snack
;
final
Completer
_transitionCompleter
=
Completer
();
late
SnackbarStatusCallback
?
_snackbarStatus
;
late
final
Alignment
?
_initialAlignment
;
late
final
Alignment
?
_endAlignment
;
bool
_wasDismissedBySwipe
=
false
;
bool
_onTappedDismiss
=
false
;
Timer
?
_timer
;
/// The animation that drives the route's transition and the previous route's
/// forward transition.
late
Animation
<
Alignment
>
_animation
;
/// The animation controller that the route uses to drive the transitions.
///
/// The animation itself is exposed by the [animation] property.
late
AnimationController
_controller
;
SnackbarStatus
?
_currentStatus
;
final
_overlayEntries
=
<
OverlayEntry
>[];
OverlayState
?
_overlayState
;
SnackbarController
(
this
.
snack
);
Future
get
future
=>
_transitionCompleter
.
future
;
bool
get
isSnackbarBeingShown
=>
_currentStatus
!=
SnackbarStatus
.
CLOSED
;
Animation
<
double
>
createBlurFilterAnimation
()
{
return
Tween
(
begin:
0.0
,
end:
snack
.
overlayBlur
).
animate
(
CurvedAnimation
(
parent:
_controller
,
curve:
const
Interval
(
0.0
,
0.35
,
curve:
Curves
.
easeInOutCirc
,
),
),
);
}
Animation
<
Color
?>
createColorOverlayColor
()
{
return
ColorTween
(
begin:
const
Color
(
0x00000000
),
end:
snack
.
overlayColor
)
.
animate
(
CurvedAnimation
(
parent:
_controller
,
curve:
const
Interval
(
0.0
,
0.35
,
curve:
Curves
.
easeInOutCirc
,
),
),
);
}
void
removeEntry
()
{
assert
(
!
_transitionCompleter
.
isCompleted
,
'Cannot remove entry from a disposed snackbar'
,
);
_cancelTimer
();
if
(
_wasDismissedBySwipe
)
{
Timer
(
const
Duration
(
milliseconds:
200
),
()
{
_controller
.
reset
();
});
_wasDismissedBySwipe
=
false
;
}
else
{
_controller
.
reverse
();
}
}
void
removeOverlay
()
{
for
(
var
element
in
_overlayEntries
)
{
element
.
remove
();
}
assert
(!
_transitionCompleter
.
isCompleted
,
'Cannot remove overlay twice.'
);
_controller
.
dispose
();
_overlayEntries
.
clear
();
_transitionCompleter
.
complete
();
}
Future
<
void
>
show
()
{
_configureOverlay
();
return
future
;
}
void
_cancelTimer
()
{
if
(
_timer
!=
null
&&
_timer
!.
isActive
)
{
_timer
!.
cancel
();
}
}
void
_configureAlignment
(
SnackPosition
snackPosition
)
{
switch
(
snack
.
snackPosition
)
{
case
SnackPosition
.
TOP
:
{
_initialAlignment
=
const
Alignment
(-
1.0
,
-
2.0
);
_endAlignment
=
const
Alignment
(-
1.0
,
-
1.0
);
break
;
}
case
SnackPosition
.
BOTTOM
:
{
_initialAlignment
=
const
Alignment
(-
1.0
,
2.0
);
_endAlignment
=
const
Alignment
(-
1.0
,
1.0
);
break
;
}
}
}
void
_configureOverlay
()
{
_overlayState
=
Overlay
.
of
(
Get
.
overlayContext
!);
_overlayEntries
.
clear
();
_overlayEntries
.
addAll
(
_createOverlayEntries
(
_getBodyWidget
()));
_overlayState
!.
insertAll
(
_overlayEntries
);
_configureSnackBarDisplay
();
}
void
_configureSnackBarDisplay
()
{
assert
(!
_transitionCompleter
.
isCompleted
,
'Cannot configure a snackbar after disposing it.'
);
_controller
=
_createAnimationController
();
_configureAlignment
(
snack
.
snackPosition
);
_snackbarStatus
=
snack
.
snackbarStatus
;
_filterBlurAnimation
=
createBlurFilterAnimation
();
_filterColorAnimation
=
createColorOverlayColor
();
_animation
=
_createAnimation
();
_animation
.
addStatusListener
(
_handleStatusChanged
);
_configureTimer
();
_controller
.
forward
();
}
void
_configureTimer
()
{
if
(
snack
.
duration
!=
null
)
{
if
(
_timer
!=
null
&&
_timer
!.
isActive
)
{
_timer
!.
cancel
();
}
_timer
=
Timer
(
snack
.
duration
!,
removeEntry
);
}
else
{
if
(
_timer
!=
null
)
{
_timer
!.
cancel
();
}
}
}
/// Called to create the animation that exposes the current progress of
/// the transition controlled by the animation controller created by
/// `createAnimationController()`.
Animation
<
Alignment
>
_createAnimation
()
{
assert
(!
_transitionCompleter
.
isCompleted
,
'Cannot create a animation from a disposed snackbar'
);
return
AlignmentTween
(
begin:
_initialAlignment
,
end:
_endAlignment
).
animate
(
CurvedAnimation
(
parent:
_controller
,
curve:
snack
.
forwardAnimationCurve
,
reverseCurve:
snack
.
reverseAnimationCurve
,
),
);
}
/// Called to create the animation controller that will drive the transitions
/// to this route from the previous one, and back to the previous route
/// from this one.
AnimationController
_createAnimationController
()
{
assert
(!
_transitionCompleter
.
isCompleted
,
'Cannot create a animationController from a disposed snackbar'
);
assert
(
snack
.
animationDuration
>=
Duration
.
zero
);
return
AnimationController
(
duration:
snack
.
animationDuration
,
debugLabel:
'
$runtimeType
'
,
vsync:
navigator
!,
);
}
Iterable
<
OverlayEntry
>
_createOverlayEntries
(
Widget
child
)
{
return
<
OverlayEntry
>[
if
(
snack
.
overlayBlur
>
0.0
)
...[
OverlayEntry
(
builder:
(
context
)
=>
GestureDetector
(
onTap:
()
{
if
(
snack
.
isDismissible
&&
!
_onTappedDismiss
)
{
_onTappedDismiss
=
true
;
Get
.
back
();
}
},
child:
AnimatedBuilder
(
animation:
_filterBlurAnimation
,
builder:
(
context
,
child
)
{
return
BackdropFilter
(
filter:
ImageFilter
.
blur
(
sigmaX:
_filterBlurAnimation
.
value
,
sigmaY:
_filterBlurAnimation
.
value
),
child:
Container
(
constraints:
const
BoxConstraints
.
expand
(),
color:
_filterColorAnimation
.
value
,
),
);
},
),
),
maintainState:
false
,
opaque:
false
,
),
],
OverlayEntry
(
builder:
(
context
)
=>
Semantics
(
child:
AlignTransition
(
alignment:
_animation
,
child:
snack
.
isDismissible
?
_getDismissibleSnack
(
child
)
:
_getSnackbarContainer
(
child
),
),
focused:
false
,
container:
true
,
explicitChildNodes:
true
,
),
maintainState:
false
,
opaque:
false
,
),
];
}
Widget
_getBodyWidget
()
{
return
Builder
(
builder:
(
_
)
{
return
GestureDetector
(
child:
snack
,
onTap:
snack
.
onTap
!=
null
?
()
=>
snack
.
onTap
?.
call
(
snack
)
:
null
,
);
});
}
DismissDirection
_getDismissDirection
()
{
if
(
snack
.
dismissDirection
==
SnackDismissDirection
.
HORIZONTAL
)
{
return
DismissDirection
.
horizontal
;
}
else
{
if
(
snack
.
snackPosition
==
SnackPosition
.
TOP
)
{
return
DismissDirection
.
up
;
}
return
DismissDirection
.
down
;
}
}
Widget
_getDismissibleSnack
(
Widget
child
)
{
return
Dismissible
(
direction:
_getDismissDirection
(),
resizeDuration:
null
,
confirmDismiss:
(
_
)
{
if
(
_currentStatus
==
SnackbarStatus
.
OPENING
||
_currentStatus
==
SnackbarStatus
.
CLOSING
)
{
return
Future
.
value
(
false
);
}
return
Future
.
value
(
true
);
},
key:
const
Key
(
'dismissible'
),
onDismissed:
(
_
)
{
_cancelTimer
();
_wasDismissedBySwipe
=
true
;
removeEntry
();
},
child:
_getSnackbarContainer
(
child
),
);
}
Widget
_getSnackbarContainer
(
Widget
child
)
{
return
Container
(
margin:
snack
.
margin
,
child:
child
,
);
}
void
_handleStatusChanged
(
AnimationStatus
status
)
{
switch
(
status
)
{
case
AnimationStatus
.
completed
:
_currentStatus
=
SnackbarStatus
.
OPEN
;
_snackbarStatus
?.
call
(
_currentStatus
);
if
(
_overlayEntries
.
isNotEmpty
)
_overlayEntries
.
first
.
opaque
=
false
;
break
;
case
AnimationStatus
.
forward
:
_currentStatus
=
SnackbarStatus
.
OPENING
;
_snackbarStatus
?.
call
(
_currentStatus
);
break
;
case
AnimationStatus
.
reverse
:
_currentStatus
=
SnackbarStatus
.
CLOSING
;
_snackbarStatus
?.
call
(
_currentStatus
);
if
(
_overlayEntries
.
isNotEmpty
)
_overlayEntries
.
first
.
opaque
=
false
;
break
;
case
AnimationStatus
.
dismissed
:
assert
(!
_overlayEntries
.
first
.
opaque
);
_currentStatus
=
SnackbarStatus
.
CLOSED
;
_snackbarStatus
?.
call
(
_currentStatus
);
removeOverlay
();
break
;
}
}
}
...
...
Please
register
or
login
to post a comment