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 17:02:59 -0300
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
307efface1f0abc6adad9f40fee2f9a05977801c
307effac
1 parent
955c18da
prevent snackbars appear simultaneosly
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
224 additions
and
226 deletions
example/lib/main.dart
lib/get_navigation/get_navigation.dart
lib/get_navigation/src/extension_navigation.dart
lib/get_navigation/src/snackbar/snack.dart
lib/get_navigation/src/snackbar/snackbar_controller.dart
example/lib/main.dart
View file @
307effa
...
...
@@ -2,28 +2,51 @@ import 'package:flutter/foundation.dart';
import
'package:flutter/material.dart'
;
import
'package:get/get.dart'
;
import
'lang/translation_service.dart'
;
import
'routes/app_pages.dart'
;
import
'shared/logger/logger_utils.dart'
;
void
main
(
)
{
runApp
(
MyApp
());
}
class
MyApp
extends
StatelessWidget
{
const
MyApp
({
Key
?
key
})
:
super
(
key:
key
);
// class MyApp extends StatelessWidget {
// const MyApp({Key? key}) : super(key: key);
// @override
// Widget build(BuildContext context) {
// return GetMaterialApp.router(
// debugShowCheckedModeBanner: false,
// enableLog: true,
// logWriterCallback: Logger.write,
// // initialRoute: AppPages.INITIAL,
// getPages: AppPages.routes,
// locale: TranslationService.locale,
// fallbackLocale: TranslationService.fallbackLocale,
// translations: TranslationService(),
// );
// }
// }
class
First
extends
StatelessWidget
{
@override
Widget
build
(
BuildContext
context
)
{
return
GetMaterialApp
.
router
(
debugShowCheckedModeBanner:
false
,
enableLog:
true
,
logWriterCallback:
Logger
.
write
,
// initialRoute: AppPages.INITIAL,
getPages:
AppPages
.
routes
,
locale:
TranslationService
.
locale
,
fallbackLocale:
TranslationService
.
fallbackLocale
,
translations:
TranslationService
(),
return
Scaffold
(
appBar:
AppBar
(
title:
Text
(
'page one'
),
leading:
IconButton
(
icon:
Icon
(
Icons
.
more
),
onPressed:
()
async
{
var
controller
=
Get
.
snackbar
(
'dsdsds'
,
'sdsdsdsds'
);
},
),
),
body:
Center
(
child:
Container
(
height:
300
,
width:
300
,
child:
ElevatedButton
(
onPressed:
()
{},
child:
Text
(
'next screen'
),
),
),
),
);
}
}
...
...
@@ -33,98 +56,68 @@ class MyApp extends StatelessWidget {
// runApp(MyApp());
// }
// class MyApp extends StatelessWidget {
// MyApp({Key? key}) : super(key: key);
// @override
// Widget build(BuildContext context) {
// return GetMaterialApp.router(
// getPages: [
// GetPage(
// participatesInRootNavigator: true,
// name: '/first',
// page: () => First()),
// GetPage(
// name: '/second',
// page: () => Second(),
// ),
// GetPage(
// name: '/third',
// page: () => Third(),
// ),
// ],
// debugShowCheckedModeBanner: false,
// );
// }
// }
class
MyApp
extends
StatelessWidget
{
MyApp
({
Key
?
key
})
:
super
(
key:
key
);
// class First extends StatelessWidget {
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// appBar: AppBar(
// title: Text('page one'),
// leading: IconButton(
// icon: Icon(Icons.more),
// onPressed: () {
// Get.changeTheme(
// context.isDarkMode ? ThemeData.light() : ThemeData.dark());
// },
// ),
// ),
// body: Center(
// child: Container(
// height: 300,
// width: 300,
// child: ElevatedButton(
// onPressed: () {},
// child: Text('next screen'),
// ),
// ),
// ),
// );
// }
// }
@override
Widget
build
(
BuildContext
context
)
{
return
GetMaterialApp
.
router
(
getPages:
[
GetPage
(
participatesInRootNavigator:
true
,
name:
'/'
,
page:
()
=>
First
()),
GetPage
(
name:
'/second'
,
page:
()
=>
Second
(),
),
GetPage
(
name:
'/third'
,
page:
()
=>
Third
(),
),
],
debugShowCheckedModeBanner:
false
,
);
}
}
// class Second extends StatelessWidget {
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// appBar: AppBar(
// title: Text('page two ${Get.parameters["id"]}'),
// ),
// body: Center(
// child: Container(
// height: 300,
// width: 300,
// child: ElevatedButton(
// onPressed: () {},
// child: Text('next screen'),
// ),
// ),
// ),
// );
// }
// }
class
Second
extends
StatelessWidget
{
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
appBar:
AppBar
(
title:
Text
(
'page two
${Get.parameters["id"]}
'
),
),
body:
Center
(
child:
Container
(
height:
300
,
width:
300
,
child:
ElevatedButton
(
onPressed:
()
{},
child:
Text
(
'next screen'
),
),
),
),
);
}
}
// class Third extends StatelessWidget {
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// backgroundColor: Colors.red,
// appBar: AppBar(
// title: Text('page three'),
// ),
// body: Center(
// child: Container(
// height: 300,
// width: 300,
// child: ElevatedButton(
// onPressed: () {},
// child: Text('go to first screen'),
// ),
// ),
// ),
// );
// }
// }
class
Third
extends
StatelessWidget
{
@override
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
backgroundColor:
Colors
.
red
,
appBar:
AppBar
(
title:
Text
(
'page three'
),
),
body:
Center
(
child:
Container
(
height:
300
,
width:
300
,
child:
ElevatedButton
(
onPressed:
()
{},
child:
Text
(
'go to first screen'
),
),
),
),
);
}
}
...
...
lib/get_navigation/get_navigation.dart
View file @
307effa
...
...
@@ -17,3 +17,4 @@ 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/snackbar_controller.dart'
;
...
...
lib/get_navigation/src/extension_navigation.dart
View file @
307effa
...
...
@@ -298,7 +298,7 @@ extension ExtensionSnackbar on GetInterface {
OnTap
?
onTap
,
Duration
duration
=
const
Duration
(
seconds:
3
),
bool
isDismissible
=
true
,
SnackDismissDirection
dismissDirection
=
SnackDismissDirection
.
VERTICAL
,
DismissDirection
?
dismissDirection
,
bool
showProgressIndicator
=
false
,
AnimationController
?
progressIndicatorController
,
Color
?
progressIndicatorBackgroundColor
,
...
...
@@ -314,7 +314,7 @@ extension ExtensionSnackbar on GetInterface {
Color
?
overlayColor
,
Form
?
userInputForm
,
})
async
{
final
getBar
=
GetBar
(
final
getBar
=
Get
Snack
Bar
(
snackbarStatus:
snackbarStatus
,
title:
title
,
message:
message
,
...
...
@@ -361,11 +361,13 @@ extension ExtensionSnackbar on GetInterface {
}
}
Future
<
void
>
showSnackbar
<
T
>(
GetBar
snackbar
)
{
return
SnackbarController
(
snackbar
).
show
();
SnackbarController
showSnackbar
(
GetSnackBar
snackbar
)
{
final
controller
=
SnackbarController
(
snackbar
);
controller
.
show
();
return
controller
;
}
void
snackbar
<
T
>
(
SnackbarController
snackbar
(
String
title
,
String
message
,
{
Color
?
colorText
,
...
...
@@ -392,7 +394,7 @@ extension ExtensionSnackbar on GetInterface {
OnTap
?
onTap
,
bool
?
isDismissible
,
bool
?
showProgressIndicator
,
Snack
DismissDirection
?
dismissDirection
,
DismissDirection
?
dismissDirection
,
AnimationController
?
progressIndicatorController
,
Color
?
progressIndicatorBackgroundColor
,
Animation
<
Color
>?
progressIndicatorValueColor
,
...
...
@@ -405,8 +407,8 @@ extension ExtensionSnackbar on GetInterface {
SnackbarStatusCallback
?
snackbarStatus
,
Color
?
overlayColor
,
Form
?
userInputForm
,
})
async
{
final
getBar
=
GetBar
(
})
{
final
getSnackBar
=
GetSnackBar
(
snackbarStatus:
snackbarStatus
,
titleText:
titleText
??
Text
(
...
...
@@ -444,7 +446,7 @@ extension ExtensionSnackbar on GetInterface {
mainButton:
mainButton
,
onTap:
onTap
,
isDismissible:
isDismissible
??
true
,
dismissDirection:
dismissDirection
??
SnackDismissDirection
.
VERTICAL
,
dismissDirection:
dismissDirection
,
showProgressIndicator:
showProgressIndicator
??
false
,
progressIndicatorController:
progressIndicatorController
,
progressIndicatorBackgroundColor:
progressIndicatorBackgroundColor
,
...
...
@@ -457,14 +459,17 @@ extension ExtensionSnackbar on GetInterface {
overlayColor:
overlayColor
??
Colors
.
transparent
,
userInputForm:
userInputForm
);
final
controller
=
SnackbarController
(
getSnackBar
);
if
(
instantInit
)
{
showSnackbar
<
T
>(
getBar
);
controller
.
show
(
);
}
else
{
//routing.isSnackbar = true;
SchedulerBinding
.
instance
!.
addPostFrameCallback
((
_
)
{
showSnackbar
<
T
>(
getBar
);
controller
.
show
(
);
});
}
return
controller
;
}
}
...
...
lib/get_navigation/src/snackbar/snack.dart
View file @
307effa
...
...
@@ -7,16 +7,18 @@ import 'package:flutter/scheduler.dart';
import
'../../../get_core/get_core.dart'
;
import
'../../get_navigation.dart'
;
typedef
OnTap
=
void
Function
(
GetBar
snack
);
typedef
OnTap
=
void
Function
(
Get
Snack
Bar
snack
);
typedef
SnackbarStatusCallback
=
void
Function
(
SnackbarStatus
?
status
);
class
Get
Bar
<
T
extends
Object
>
extends
StatefulWidget
{
class
Get
SnackBar
extends
StatefulWidget
{
/// A callback for you to listen to the different Snack status
final
SnackbarStatusCallback
?
snackbarStatus
;
/// The title displayed to the user
final
String
?
title
;
final
DismissDirection
?
dismissDirection
;
/// The message displayed to the user.
final
String
?
message
;
...
...
@@ -112,11 +114,6 @@ class GetBar<T extends Object> extends StatefulWidget {
/// [SnackPosition.BOTTOM] is the default.
final
SnackPosition
snackPosition
;
/// [SnackDismissDirection.VERTICAL] by default.
/// Can also be [SnackDismissDirection.HORIZONTAL] in which case both left
/// and right dismiss are allowed.
final
SnackDismissDirection
dismissDirection
;
/// Snack can be floating or be grounded to the edge of the screen.
/// If grounded, I do not recommend using [margin] or [borderRadius].
/// [SnackStyle.FLOATING] is the default
...
...
@@ -154,7 +151,7 @@ class GetBar<T extends Object> extends StatefulWidget {
/// Every other widget is ignored if this is not null.
final
Form
?
userInputForm
;
const
GetBar
({
const
Get
Snack
Bar
({
Key
?
key
,
this
.
title
,
this
.
message
,
...
...
@@ -176,7 +173,7 @@ class GetBar<T extends Object> extends StatefulWidget {
this
.
onTap
,
this
.
duration
,
this
.
isDismissible
=
true
,
this
.
dismissDirection
=
SnackDismissDirection
.
VERTICAL
,
this
.
dismissDirection
,
this
.
showProgressIndicator
=
false
,
this
.
progressIndicatorController
,
this
.
progressIndicatorBackgroundColor
,
...
...
@@ -194,13 +191,11 @@ class GetBar<T extends Object> extends StatefulWidget {
})
:
super
(
key:
key
);
@override
State
createState
()
{
return
_GetBarState
<
T
>();
}
State
createState
()
=>
_GetSnackBarState
();
/// Show the snack. It's call [SnackbarStatus.OPENING] state
/// followed by [SnackbarStatus.OPEN]
Future
<
void
>
show
<
T
>()
async
{
SnackbarController
show
()
{
return
Get
.
showSnackbar
(
this
);
}
}
...
...
@@ -215,21 +210,14 @@ class GetBar<T extends Object> extends StatefulWidget {
/// 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
_Get
BarState
<
K
extends
Object
>
extends
State
<
Get
Bar
>
class
_Get
SnackBarState
extends
State
<
GetSnack
Bar
>
with
TickerProviderStateMixin
{
SnackbarStatus
?
currentStatus
;
AnimationController
?
_fadeController
;
late
Animation
<
double
>
_fadeAnimation
;
...
...
@@ -251,7 +239,7 @@ class _GetBarState<K extends Object> extends State<GetBar>
late
CurvedAnimation
_progressAnimation
;
GlobalKey
backgroundBoxKey
=
GlobalKey
();
final
_
backgroundBoxKey
=
GlobalKey
();
@override
Widget
build
(
BuildContext
context
)
{
...
...
@@ -339,8 +327,7 @@ Set either a message or messageText""");
void
_configureLeftBarFuture
()
{
SchedulerBinding
.
instance
!.
addPostFrameCallback
(
(
_
)
{
final
keyContext
=
backgroundBoxKey
.
currentContext
;
final
keyContext
=
_backgroundBoxKey
.
currentContext
;
if
(
keyContext
!=
null
)
{
final
box
=
keyContext
.
findRenderObject
()
as
RenderBox
;
_boxHeightCompleter
.
complete
(
box
.
size
);
...
...
@@ -386,7 +373,7 @@ Set either a message or messageText""");
Widget
_generateInputSnack
()
{
return
Container
(
key:
backgroundBoxKey
,
key:
_
backgroundBoxKey
,
constraints:
widget
.
maxWidth
!=
null
?
BoxConstraints
(
maxWidth:
widget
.
maxWidth
!)
:
null
,
...
...
@@ -413,7 +400,7 @@ Set either a message or messageText""");
Widget
_generateSnack
()
{
return
Container
(
key:
backgroundBoxKey
,
key:
_
backgroundBoxKey
,
constraints:
widget
.
maxWidth
!=
null
?
BoxConstraints
(
maxWidth:
widget
.
maxWidth
!)
:
null
,
...
...
lib/get_navigation/src/snackbar/snackbar_controller.dart
View file @
307effa
...
...
@@ -6,28 +6,30 @@ import 'package:flutter/material.dart';
import
'../../../get.dart'
;
class
SnackbarController
{
static
final
_queue
=
GetQueue
();
late
Animation
<
double
>
_filterBlurAnimation
;
late
Animation
<
Color
?>
_filterColorAnimation
;
final
GetBar
<
Object
>
snack
;
final
Completer
_transitionCompleter
=
Completer
();
late
SnackbarStatusCallback
?
_snackbarStatus
;
final
GetSnackBar
snack
;
final
_transitionCompleter
=
Completer
<
SnackbarController
>();
late
SnackbarStatusCallback
?
_snackbarStatus
;
late
final
Alignment
?
_initialAlignment
;
late
final
Alignment
?
_endAlignment
;
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
;
late
final
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
;
late
final
AnimationController
_controller
;
SnackbarStatus
?
_currentStatus
;
...
...
@@ -37,72 +39,20 @@ class SnackbarController {
SnackbarController
(
this
.
snack
);
Future
get
future
=>
_transitionCompleter
.
future
;
Future
<
SnackbarController
>
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
>
close
()
async
{
_removeEntry
();
await
future
;
}
Future
<
void
>
show
()
{
_configureOverlay
();
return
future
;
return
_queue
.
add
(
_show
);
}
// ignore: avoid_returning_this
void
_cancelTimer
()
{
if
(
_timer
!=
null
&&
_timer
!.
isActive
)
{
_timer
!.
cancel
();
...
...
@@ -138,12 +88,10 @@ class SnackbarController {
assert
(!
_transitionCompleter
.
isCompleted
,
'Cannot configure a snackbar after disposing it.'
);
_controller
=
_createAnimationController
();
_configureAlignment
(
snack
.
snackPosition
);
_snackbarStatus
=
snack
.
snackbarStatus
;
_filterBlurAnimation
=
createBlurFilterAnimation
();
_filterColorAnimation
=
createColorOverlayColor
();
_filterBlurAnimation
=
_createBlurFilterAnimation
();
_filterColorAnimation
=
_createColorOverlayColor
();
_animation
=
_createAnimation
();
_animation
.
addStatusListener
(
_handleStatusChanged
);
_configureTimer
();
...
...
@@ -155,7 +103,7 @@ class SnackbarController {
if
(
_timer
!=
null
&&
_timer
!.
isActive
)
{
_timer
!.
cancel
();
}
_timer
=
Timer
(
snack
.
duration
!,
removeEntry
);
_timer
=
Timer
(
snack
.
duration
!,
_
removeEntry
);
}
else
{
if
(
_timer
!=
null
)
{
_timer
!.
cancel
();
...
...
@@ -192,6 +140,33 @@ class SnackbarController {
);
}
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
,
),
),
);
}
Iterable
<
OverlayEntry
>
_createOverlayEntries
(
Widget
child
)
{
return
<
OverlayEntry
>[
if
(
snack
.
overlayBlur
>
0.0
)
...[
...
...
@@ -249,20 +224,16 @@ class SnackbarController {
});
}
DismissDirection
_getDismissDirection
()
{
if
(
snack
.
dismissDirection
==
SnackDismissDirection
.
HORIZONTAL
)
{
return
DismissDirection
.
horizontal
;
}
else
{
if
(
snack
.
snackPosition
==
SnackPosition
.
TOP
)
{
return
DismissDirection
.
up
;
}
return
DismissDirection
.
down
;
DismissDirection
_getDefaultDismissDirection
()
{
if
(
snack
.
snackPosition
==
SnackPosition
.
TOP
)
{
return
DismissDirection
.
up
;
}
return
DismissDirection
.
down
;
}
Widget
_getDismissibleSnack
(
Widget
child
)
{
return
Dismissible
(
direction:
_ge
tDismissDirection
(),
direction:
snack
.
dismissDirection
??
_getDefaul
tDismissDirection
(),
resizeDuration:
null
,
confirmDismiss:
(
_
)
{
if
(
_currentStatus
==
SnackbarStatus
.
OPENING
||
...
...
@@ -273,9 +244,7 @@ class SnackbarController {
},
key:
const
Key
(
'dismissible'
),
onDismissed:
(
_
)
{
_cancelTimer
();
_wasDismissedBySwipe
=
true
;
removeEntry
();
_onDismiss
();
},
child:
_getSnackbarContainer
(
child
),
);
...
...
@@ -309,8 +278,51 @@ class SnackbarController {
assert
(!
_overlayEntries
.
first
.
opaque
);
_currentStatus
=
SnackbarStatus
.
CLOSED
;
_snackbarStatus
?.
call
(
_currentStatus
);
removeOverlay
();
_
removeOverlay
();
break
;
}
}
void
_onDismiss
()
{
_cancelTimer
();
_wasDismissedBySwipe
=
true
;
_removeEntry
();
}
void
_registerSnackbar
()
{}
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
(
this
);
}
Future
<
void
>
_show
()
{
_configureOverlay
();
return
future
;
}
void
_unRegisterSnackbar
()
{}
}
...
...
Please
register
or
login
to post a comment