├── .gitignore
├── LICENSE
├── README.md
└── peek_and_pop
├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── example
├── .flutter-plugins-dependencies
├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── assets
│ ├── 0.jpeg
│ ├── 1.jpeg
│ ├── 10.jpeg
│ ├── 11.jpeg
│ ├── 12.jpeg
│ ├── 13.jpeg
│ ├── 14.jpeg
│ ├── 15.jpeg
│ ├── 16.jpeg
│ ├── 17.jpeg
│ ├── 18.jpeg
│ ├── 19.jpeg
│ ├── 2.jpeg
│ ├── 20.jpeg
│ ├── 21.jpeg
│ ├── 22.jpeg
│ ├── 23.jpeg
│ ├── 24.jpeg
│ ├── 25.jpeg
│ ├── 26.jpeg
│ ├── 27.jpeg
│ ├── 28.jpeg
│ ├── 29.jpeg
│ ├── 3.jpeg
│ ├── 4.jpeg
│ ├── 5.jpeg
│ ├── 6.jpeg
│ ├── 7.jpeg
│ ├── 8.jpeg
│ ├── 9.jpeg
│ ├── Hero.png
│ └── Scenery.jpeg
├── lib
│ ├── main.dart
│ └── nav_bar.dart
├── pubspec.lock
├── pubspec.yaml
└── test
│ └── example_test.dart
├── lib
├── Export.dart
├── animated_cross_fade.dart
├── gesture_detector.dart
├── misc.dart
├── peek_and_pop.dart
├── peek_and_pop_child.dart
├── peek_and_pop_controller.dart
└── peek_and_pop_detector.dart
├── pretty_example
├── .flutter-plugins-dependencies
├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── assets
│ ├── 0.jpeg
│ ├── 1.jpeg
│ ├── 10.jpeg
│ ├── 11.jpeg
│ ├── 12.jpeg
│ ├── 13.jpeg
│ ├── 14.jpeg
│ ├── 15.jpeg
│ ├── 16.jpeg
│ ├── 17.jpeg
│ ├── 18.jpeg
│ ├── 19.jpeg
│ ├── 2.jpeg
│ ├── 20.jpeg
│ ├── 21.jpeg
│ ├── 22.jpeg
│ ├── 23.jpeg
│ ├── 24.jpeg
│ ├── 25.jpeg
│ ├── 26.jpeg
│ ├── 27.jpeg
│ ├── 28.jpeg
│ ├── 29.jpeg
│ ├── 3.jpeg
│ ├── 4.jpeg
│ ├── 5.jpeg
│ ├── 6.jpeg
│ ├── 7.jpeg
│ ├── 8.jpeg
│ ├── 9.jpeg
│ ├── Hero.png
│ └── Scenery.jpeg
├── lib
│ ├── main.dart
│ └── nav_bar.dart
├── pubspec.lock
├── pubspec.yaml
└── test
│ └── pretty_example_test.dart
├── pubspec.lock
├── pubspec.yaml
└── test
└── peek_and_pop_test.dart
/.gitignore:
--------------------------------------------------------------------------------
1 | /gitignore
2 | /android
3 | /build
4 | /ios
5 | .notes.md
6 | .notes.txt
7 |
8 | # Miscellaneous
9 | *.class
10 | *.log
11 | *.pyc
12 | *.swp
13 | .DS_Store
14 | .atom/
15 | .buildlog/
16 | .history
17 | .svn/
18 |
19 | # IntelliJ related
20 | *.iml
21 | *.ipr
22 | *.iws
23 | .idea/
24 |
25 | # The .vscode folder contains launch configuration and tasks you configure in
26 | # VS Code which you may wish to be included in version control, so this line
27 | # is commented out by default.
28 | #.vscode/
29 |
30 | # Flutter/Dart/Pub related
31 | **/doc/api/
32 | .dart_tool/
33 | .flutter-plugins
34 | .packages
35 | .pub-cache/
36 | .pub/
37 | build/
38 |
39 | # Android related
40 | **/android/**/gradle-wrapper.jar
41 | **/android/.gradle
42 | **/android/captures/
43 | **/android/gradlew
44 | **/android/gradlew.bat
45 | **/android/local.properties
46 | **/android/**/GeneratedPluginRegistrant.java
47 |
48 | # iOS/XCode related
49 | **/ios/**/*.mode1v3
50 | **/ios/**/*.mode2v3
51 | **/ios/**/*.moved-aside
52 | **/ios/**/*.pbxuser
53 | **/ios/**/*.perspectivev3
54 | **/ios/**/*sync/
55 | **/ios/**/.sconsign.dblite
56 | **/ios/**/.tags*
57 | **/ios/**/.vagrant/
58 | **/ios/**/DerivedData/
59 | **/ios/**/Icon?
60 | **/ios/**/Pods/
61 | **/ios/**/.symlinks/
62 | **/ios/**/profile
63 | **/ios/**/xcuserdata
64 | **/ios/.generated/
65 | **/ios/Flutter/App.framework
66 | **/ios/Flutter/Flutter.framework
67 | **/ios/Flutter/Generated.xcconfig
68 | **/ios/Flutter/app.flx
69 | **/ios/Flutter/app.zip
70 | **/ios/Flutter/flutter_assets/
71 | **/ios/ServiceDefinitions.json
72 | **/ios/Runner/GeneratedPluginRegistrant.*
73 |
74 | # Exceptions to above rules.
75 | !**/ios/**/default.mode1v3
76 | !**/ios/**/default.mode2v3
77 | !**/ios/**/default.pbxuser
78 | !**/ios/**/default.perspectivev3
79 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
80 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Ali Yigit Bireroglu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # peek_and_pop
2 |
3 | [comment]: <> (Badges)
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | [](https://pub.dev/packages/peek_and_pop)
18 | [](https://github.com/aliyigitbireroglu/flutter-peek-and-pop/blob/master/LICENSE)
19 |
20 | [comment]: <> (Introduction)
21 |
22 |
23 | Peek & Pop implementation for Flutter based on the iOS functionality of the same name.
24 |
25 | **Finally, the v1.0.0 release! More fluent, more optimised and more beautiful than ever. Very customisable and very easy to use.**
26 |
27 | **It is highly recommended to read the documentation and run the example project on a real device to fully understand and inspect the full range of
28 | capabilities.**
29 |
30 | [comment]: <> (ToC)
31 | [Media](#media) | [Description](#description) | [Installation](#installation) | [How-to-Use](#howtouse)
32 |
33 | [comment]: <> (Notice)
34 | ## Notice
35 | * **v0.1.9 and higher no longer requires any modifications to Flutter's normal "binding.dart"! You can leave your Flutter source code alone and happy.**
36 |
37 | * **If you are updating from an earlier version, you can revert your "binding.dart" to its original format.**
38 | * * *
39 | [comment]: <> (Recent)
40 | ## Recent
41 | * **The "Quick Actions" feature is now added. It is highly customisable and you can show a dynamic menu with quick action buttons as the view is
42 | dragged and snapped very easily. The drag and snap limits will be automatically set according to the menu and the view.
43 | [snap](https://pub.dev/packages/snap) is now implemented directly to the package. See [Media](#media) for examples.**
44 |
45 | * **The "Overlap" and "Alignment" features are now added. These two features create a much more fluent Peek & Pop process that is much more similar
46 | to the actual iOS version. See [Media](#media) for examples.**
47 |
48 | * **The "Scale Up" and "Scale Down" features are now added. You can use these features to scale a widget down or up as the Peek & Pop process
49 | proceeds. "Scale Up" is also supported for the "Indicator" feature out of the box.See [Media](#media) for examples.**
50 |
51 | * **Improved enumeration for the stage of the Peek & Pop process.**
52 |
53 | * **The "Indicator" feature is now added. See [Media](#media) for examples.**
54 |
55 | * **Animations are now up to 4x faster with the new optimised blur effect algorithm during the Peek & Pop process.**
56 | * * *
57 | [comment]: <> (Warning)
58 | ## Warning
59 | * **"isHero" is now removed. It wasn't playing well with the package algorithm and it is considered to be unnecessary for the Peek & Pop process.
60 | However, this shouldn't be a problem due to the addition of the new "Overlap" and "Alignment" features. If you must use a Hero widget, only use it
61 | while "willBeDone" or "isDone" is true.**
62 |
63 | * **Old installation instructions are removed. If you wish (for some reason) to use a version older than v0.1.9, see the README of that version for
64 | the relevant installation instructions.**
65 | * * *
66 |
67 |
68 | [comment]: <> (Media)
69 |
70 | ## Media
71 |
72 | Watch on **Youtube**:
73 |
74 | [**v1.0.0 Showcase Demo**](https://youtu.be/IQq_ty5mRYU) | [**v1.0.0 Technical Preview**](https://youtu.be/hIjoWfP0krA)
75 |
76 | [v0.1.7](https://youtu.be/wOWCV7HJzwc)
77 |
78 | [v0.1.0 Mixed](https://youtu.be/G5QLwGtcb1I)
79 |
80 | [v0.0.1 Normal](https://youtu.be/PaEpU31z_7Q) | [v0.0.1 Moveable](https://youtu.be/3TjCFwHoOiE) | [v0.0.1 Platform View](https://youtu.be/489YB-QuJ3k) | [v0.0.1 Hero](https://youtu.be/36DAwnFKSKI)
81 |
82 |
83 |
84 |
85 |
86 |
87 | [comment]: <> (Description)
88 |
89 | ## Description
90 | As a fan of the iOS Peek & Pop functionality, I decided to implement it for Flutter as well.
91 |
92 | The package has been tested on iOS but not yet on Android as I don't have access to an Android device with Force Press capabilities. Help about
93 | this would be appreciated.
94 |
95 | ~~For devices that don't support Force Press, the package comes with an adaptation to Long Press *however* the Long Press version of this package is
96 | still under development and is not yet fully tested so consider it as a developers preview.~~
97 |
98 | (The Long Press version is temporarily removed. It will be added back soon.)
99 |
100 | ##
101 | The power move of this package is what I like to call "Gesture Recognition Rerouting". Normally, when a new widget with GestureDetector or similar
102 | is pushed over an initial widget used for detecting Force Press or when Navigator is used to pop a new page, the user has to restart the gesture
103 | for Flutter to resume updating it. This package fixes that problem as explained in the documentation:
104 |
105 | ```
106 | //This function is called by the instantiated [PeekAndPopChild] once it is ready to be included in the Peek & Pop process. Perhaps the most
107 | //essential functionality of this package also takes places in this function: The gesture recognition is rerouted from the [PeekAndPopDetector]
108 | //to the instantiated [PeekAndPopChild]. This is important for avoiding the necessity of having the user stop and restart their Force Press.
109 | //Instead, the [PeekAndPopController] does this automatically so that the existing Force Press can continue to update even when if
110 | //[PeekAndPopDetector] is blocked by the view which is often the case especially when using PlatformViews.
111 | ```
112 |
113 |
114 | [comment]: <> (Installation)
115 |
116 | ## Installation
117 | *It is easy. Don't worry.*
118 |
119 | **If you do not wish to use PlatformViews you can skip the installation instructions.**
120 |
121 | **Old installation instructions are removed. If you wish (for some reason) to use a version older than v0.1.9, see the README of that version for
122 | the relevant installation instructions.**
123 |
124 | For properly displaying PlatformViews, this package requires the latest Flutter [master](https://github.com/flutter/flutter)
125 | branch. *Maybe* it will work with some other version too but tests made with the [webview_flutter](https://pub.flutter-io.cn/packages/webview_flutter)
126 | seem to only properly display with the latest Flutter [master](https://github.com/flutter/flutter) branch which has improved the PlatformViews that
127 | allow better functionalities such as proper scaling and proper clipping.
128 |
129 | If you do not wish to use PlatformViews, you can skip this step.
130 |
131 | To use latest Flutter [master](https://github.com/flutter/flutter) branch, run the following command.
132 |
133 | **Note**: Don't forget to add io.flutter.embedded_views_previewYES to your Info.plist. See
134 | [webview_flutter](https://pub.flutter-io.cn/packages/webview_flutter) for more info.
135 |
136 | ```
137 | $ git clone -b master https://github.com/flutter/flutter.git
138 | $ flutter channel master
139 | $ flutter upgrade
140 | $ flutter doctor
141 | $ ./flutter/bin/flutter --version
142 | ```
143 |
144 |
145 | [comment]: <> (How-to-Use)
146 |
147 | ## How-to-Use
148 | *Also easy.*
149 |
150 | First of all, as explained in the documentation:
151 |
152 | ```
153 | //I noticed that a fullscreen blur effect via the [BackdropFilter] widget is not good to use while running the animations required for the Peek &
154 | //Pop process as it causes a noticeable drop in the framerate- especially for devices with high resolutions. During a mostly static view, the
155 | //drop is acceptable. However, once the animations start running, this drop causes a visual disturbance. To prevent this, a new optimised blur
156 | //effect algorithm is implemented. Now, the [BackdropFilter] widget is only used until the animations are about to start. At that moment, it is
157 | //replaced by a static image. Therefore, to capture this image, your root CupertinoApp/MaterialApp MUST be wrapped in a [RepaintBoundary] widget
158 | //which uses the [background] key. As a result, the Peek & Pop process is now up to 4x more fluent.
159 | ```
160 |
161 | TL;DR: Wrap your root CupertinoApp/MaterialApp in a RepaintBoundary widget and use the background GlobalKey from "misc.dart".
162 |
163 | This is required for the new optimised blur effect algorithm:
164 |
165 | ```
166 | import 'package:peek_and_pop/misc.dart' as PeekAndPopMisc;
167 |
168 | class MyApp extends StatelessWidget {
169 | @override
170 | Widget build(BuildContext context) {
171 | return RepaintBoundary(
172 | key: PeekAndPopMisc.background,
173 | child: MaterialApp(
174 | title: 'Peek & Pop Demo',
175 | home: MyHomePage(title: 'Peek & Pop Demo')
176 | )
177 | );
178 | }
179 | }
180 | ```
181 |
182 | If you wish to use the "ScaleUp" or the "Scale Down" features, wrap the widgets you wish to scale down or scale up during the Peek & Pop process with
183 | the scaleUpWrapper and scaleDownWrapper functions from "misc.dart":
184 |
185 | ```
186 | @override
187 | Widget build(BuildContext context) {
188 | return Scaffold(
189 | appBar: AppBar(title: Text(widget.title)),
190 | body: PeekAndPopMisc.scaleDownWrapper(
191 | ...,
192 | 0.04,
193 | ),
194 | );
195 | }
196 | ```
197 |
198 | Then, create a PeekAndPopController such as:
199 |
200 | ```
201 | PeekAndPopController(
202 | uiChild(), //Widget uiChild
203 | false, //bool uiChildUseCache
204 | {Key key,
205 | peekAndPopBuilder,
206 | peekAndPopBuilderUseCache,
207 | peekAndPopBuilderAtPeek : peekAndPopBuilderAtPeek,
208 | peekAndPopBuilderAtPop : peekAndPopBuilderAtPop,
209 | quickActionsBuilder : quickActionsBuilder,
210 | sigma : 10,
211 | backdropColor : Colors.black,
212 | alpha : 126,
213 | overlayBuilder : overlayBuilder,
214 | useOverlap : true,
215 | customOverlapRect,
216 | useAlignment, : false,
217 | useIndicator : true,
218 | indicatorScaleUpCoefficient : 0.01,
219 | willPeekAndPopComplete : _willPeekAndPopComplete,
220 | willPushPeekAndPop : _willPushPeekAndPop,
221 | willUpdatePeekAndPop : _willUpdatePeekAndPop,
222 | willCancelPeekAndPop : _willCancelPeekAndPop,
223 | willFinishPeekAndPop : _willFinishPeekAndPop,
224 | willClosePeekAndPop : _willClosePeekAndPop,
225 | onPeekAndPopComplete : _onPeekAndPopComplete,
226 | onPushPeekAndPop : _onPushPeekAndPop,
227 | onUpdatePeekAndPop : _onUpdatePeekAndPop,
228 | onCancelPeekAndPop : _onCancelPeekAndPop,
229 | onFinishPeekAndPop : _onFinishPeekAndPop,
230 | onClosePeekAndPop : _onFinishPeekAndPop,
231 | onPressStart : _onPressStart,
232 | onPressUpdate : _onPressUpdate,
233 | onPressEnd : _onPressEnd,
234 | treshold : 0.5,
235 | startPressure : 0.125,
236 | peakPressure : 1.0,
237 | peekScale : 0.5,
238 | peekCoefficient : 0.05,
239 | popTransition,
240 | useHaptics : true})
241 |
242 | Widget uiChild() {}
243 |
244 | Widget peekAndPopBuilderAtPeek(BuildContext context, PeekAndPopControllerState _peekAndPopController);
245 | Widget peekAndPopBuilderAtPop(BuildContext context, PeekAndPopControllerState _peekAndPopController);
246 |
247 | QuickActionsData quickActionsBuilder(PeekAndPopControllerState _peekAndPopController);
248 |
249 | WidgetBuilder overlayBuiler(BuildContext context);
250 |
251 | bool _willPeekAndPopComplete(PeekAndPopControllerState _peekAndPopController);
252 | bool _willPushPeekAndPop(PeekAndPopControllerState _peekAndPopController);
253 | bool _willUpdatePeekAndPop(PeekAndPopControllerState _peekAndPopController);
254 | bool _willCancelPeekAndPop(PeekAndPopControllerState _peekAndPopController);
255 | bool _willFinishPeekAndPop(PeekAndPopControllerState _peekAndPopController);
256 | bool _willClosePeekAndPop(PeekAndPopControllerState _peekAndPopController);
257 |
258 | void _onPeekAndPopComplete(PeekAndPopControllerState _peekAndPopController);
259 | void _onPushPeekAndPop(PeekAndPopControllerState _peekAndPopController);
260 | void _onUpdatePeekAndPop(PeekAndPopControllerState _peekAndPopController);
261 | void _onCancelPeekAndPop(PeekAndPopControllerState _peekAndPopController);
262 | void _onFinishPeekAndPop(PeekAndPopControllerState _peekAndPopController);
263 | void _onClosePeekAndPop(PeekAndPopControllerState _peekAndPopController);
264 |
265 | void _onPressStart(dynamic dragDetails);
266 | void _onPressUpdate(dynamic dragDetails);
267 | void _onPressEnd(dynamic dragDetails);
268 |
269 | ```
270 |
271 | **Further Explanations:**
272 |
273 | *For a complete set of descriptions for all parameters and methods, see the [documentation](https://pub.dev/documentation/peek_and_pop/latest/).*
274 |
275 | * Set [uiChildUseCache] to true if your [uiChild] doesn't change during the Peek & Pop process.
276 | * Set [peekAndPopBuilderUseCache] to true if your [peekAndPopBuilder] doesn't change during the Peek & Pop process.
277 | * If [peekAndPopBuilderAtPop] and [peekAndPopBuilderAtPeek] are set, [peekAndPopBuilder] and [peekAndPopBuilderUseCache] are ignored.
278 | * If one of [peekAndPopBuilderAtPop] and [peekAndPopBuilderAtPeek] is set, the other one must be set too.
279 | * If [quickActionsBuilder] is set, it is recommended that [peekAndPopBuilderAtPop] and [peekAndPopBuilderAtPop] are set too.
280 | * [overlayBuilder] is an optional second view to be displayed during the Peek & Pop process. This entire widget is built after everything else.
281 | * For all [PeekAndPopProcessNotifier] callbacks such as [willPeekAndPopComplete], you can return false to prevent the default action.
282 | * All [PeekAndPopProcessNotifier] and [PeekAndPopProcessCallback] callbacks will return a reference to the created [PeekAndPopController] state.
283 | You can save this instance for further actions.
284 | * [pageTransition] is the transition to be used when the view is opened directly or when the view is closed. A default [SlideTransition] is provided.
285 | * Use [PeekAndPopControllerState]'s [void closePeekAndPop()] method to close the Peek & Pop process. Do not call [Navigator.of(context).pop()]
286 | directly.
287 | * Use [PeekAndPopControllerState]'s [stage] variable to get enumeration for the stage of the Peek & Pop process. If you want to only know when the
288 | Peek & Pop process will be or is completed, you can also use [willBeDone] or [isDone] variables.
289 |
290 |
291 | [comment]: <> (Notes)
292 | ## Notes
293 | I started using and learning Flutter only some weeks ago so this package might have some parts that don't make sense, that should be completely
294 | different, that could be much better, etc. Please let me know! Nicely!
295 |
296 | Any help, suggestion or criticism is appreciated!
297 |
298 | Cheers.
299 |
300 | [comment]: <> (CosmosSoftware)
301 |
302 |
303 |
--------------------------------------------------------------------------------
/peek_and_pop/.gitignore:
--------------------------------------------------------------------------------
1 | /gitignore
2 | /android
3 | /build
4 | /ios
5 | .notes.md
6 | .notes.txt
7 |
8 | # Miscellaneous
9 | *.class
10 | *.log
11 | *.pyc
12 | *.swp
13 | .DS_Store
14 | .atom/
15 | .buildlog/
16 | .history
17 | .svn/
18 |
19 | # IntelliJ related
20 | *.iml
21 | *.ipr
22 | *.iws
23 | .idea/
24 |
25 | # The .vscode folder contains launch configuration and tasks you configure in
26 | # VS Code which you may wish to be included in version control, so this line
27 | # is commented out by default.
28 | #.vscode/
29 |
30 | # Flutter/Dart/Pub related
31 | **/doc/api/
32 | .dart_tool/
33 | .flutter-plugins
34 | .packages
35 | .pub-cache/
36 | .pub/
37 | build/
38 |
39 | # Android related
40 | **/android/**/gradle-wrapper.jar
41 | **/android/.gradle
42 | **/android/captures/
43 | **/android/gradlew
44 | **/android/gradlew.bat
45 | **/android/local.properties
46 | **/android/**/GeneratedPluginRegistrant.java
47 |
48 | # iOS/XCode related
49 | **/ios/**/*.mode1v3
50 | **/ios/**/*.mode2v3
51 | **/ios/**/*.moved-aside
52 | **/ios/**/*.pbxuser
53 | **/ios/**/*.perspectivev3
54 | **/ios/**/*sync/
55 | **/ios/**/.sconsign.dblite
56 | **/ios/**/.tags*
57 | **/ios/**/.vagrant/
58 | **/ios/**/DerivedData/
59 | **/ios/**/Icon?
60 | **/ios/**/Pods/
61 | **/ios/**/.symlinks/
62 | **/ios/**/profile
63 | **/ios/**/xcuserdata
64 | **/ios/.generated/
65 | **/ios/Flutter/App.framework
66 | **/ios/Flutter/Flutter.framework
67 | **/ios/Flutter/Generated.xcconfig
68 | **/ios/Flutter/app.flx
69 | **/ios/Flutter/app.zip
70 | **/ios/Flutter/flutter_assets/
71 | **/ios/ServiceDefinitions.json
72 | **/ios/Runner/GeneratedPluginRegistrant.*
73 |
74 | # Exceptions to above rules.
75 | !**/ios/**/default.mode1v3
76 | !**/ios/**/default.mode2v3
77 | !**/ios/**/default.pbxuser
78 | !**/ios/**/default.perspectivev3
79 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
80 |
--------------------------------------------------------------------------------
/peek_and_pop/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 20e59316b8b8474554b38493b8ca888794b0234a
8 | channel: stable
9 |
10 | project_type: package
11 |
--------------------------------------------------------------------------------
/peek_and_pop/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [1.0.3] - 21.11.2019
2 |
3 | * Minor changes.
4 |
5 | ## [1.0.2] - 07.09.2019
6 |
7 | * Two new PeekAndPopBuilders are added to [PeekAndPopController]. Use [PeekAndPopController.peekAndPopBuilderAtPeek] and
8 | [PeekAndPopController.peekAndPopBuilderAtPop] for both convenience and improved performance.
9 |
10 | * Improved performance.
11 |
12 | * [1.0.2+1] Support for latest dependencies.
13 |
14 | ## [1.0.1] - 03.09.2019
15 |
16 | * Minor changes.
17 |
18 | ## [1.0.0] - 30.08.2019
19 |
20 | * The "Quick Actions" feature is now added. It is highly customisable and you can show a dynamic menu with quick action buttons as the view is
21 | dragged and snapped very easily. The drag and snap limits will be automatically set according to the menu and the view.
22 | [snap](https://pub.dev/packages/snap) is now implemented directly to the package. See this [video](https://youtu.be/IQq_ty5mRYU) for examples.
23 |
24 | * The "Overlap" and "Alignment" features are now added. These two features create a much more fluent Peek & Pop process that is much more similar
25 | to the actual iOS version. See this [video](https://youtu.be/IQq_ty5mRYU) for examples.
26 |
27 | * The "Scale Up" and "Scale Down" features are now added. You can use these features to scale a widget down or up as the Peek & Pop process
28 | proceeds. "Scale Up" is also supported for the "Indicator" feature out of the box. See this [video](https://youtu.be/IQq_ty5mRYU) for examples.
29 |
30 | * "isHero" is now removed. It wasn't playing well with the package algorithm and it is considered to be unnecessary for the Peek & Pop process.
31 | However, this shouldn't be a problem due to the addition of the new "Overlap" and "Alignment" features. If you must use a Hero widget, only use it
32 | while "willBeDone" or "isDone" is true.
33 |
34 | * A workaround is implemented to avoid a Flutter Engine bug that was causing trouble with the optimised blur effect algorithm.
35 |
36 | * Improved enumeration for the stage of the Peek & Pop process.
37 |
38 | * Improved performance.
39 |
40 | * Fine tuning.
41 |
42 | * Improved code style.
43 |
44 | * Improved example project.
45 |
46 | * Updated README.
47 |
48 | * Old installation instructions are removed. If you wish (for some reason) to use a version older than v0.1.9, see the README of that version for
49 | the relevant installation instructions.
50 |
51 | ## [0.2.0] - 23.08.2019
52 |
53 | * Improved performance.
54 |
55 | * Minor changes.
56 |
57 | * Improved code style with trailing commas.
58 |
59 | * [0.2.0+1] Minor changes.
60 |
61 | ## [0.1.9] - 20.08.2019
62 |
63 | * Modifications to Flutter's normal "binding.dart" are no longer required!
64 |
65 | * The Long Press version is temporarily removed. It will be added back soon.
66 |
67 | * Code excerpt added to the README.
68 |
69 | * Updated README.
70 |
71 | * [0.1.9+1] Updated README.
72 |
73 | ## [0.1.8] - 18.08.2019
74 |
75 | * Example project adapted to the updated [snap](https://pub.dev/packages/snap).
76 |
77 | * Minor changes.
78 |
79 | * [0.1.8+1] Updated README.
80 |
81 | ## [0.1.7] - 14.08.2019
82 |
83 | * The "Indicator" feature added. See this [video](https://youtu.be/wOWCV7HJzwc) for examples.
84 |
85 | * Improved performance.
86 |
87 | * Fine tuning.
88 |
89 | ## [0.1.6] - 12.08.2019
90 |
91 | * Improved Long Press version (still under development).
92 |
93 | * Fine tuning.
94 |
95 | * Improved documentation.
96 |
97 | * Updated README.
98 |
99 | ## [0.1.5] - 11.08.2019
100 |
101 | * Improved performance.
102 |
103 | * Improved code style.
104 |
105 | ## [0.1.4] - 11.08.2019
106 |
107 | * A minor bug is fixed.
108 |
109 | ## [0.1.3] - 07.08.2019
110 |
111 | * A minor bug in the example project is fixed.
112 |
113 | * Updated README:
114 |
115 | **Note**: Don't forget to add io.flutter.embedded_views_previewYES to your Info.plist. See
116 | [webview_flutter](https://pub.flutter-io.cn/packages/webview_flutter) for more info.
117 |
118 | ## [0.1.2] - 07.08.2019
119 |
120 | * [snap](https://pub.dev/packages/snap) is now implemented directly to the example.
121 |
122 | * More callbacks added for better control.
123 |
124 | * Simple enumeration for the stage of the Peek & Pop process added.
125 |
126 | * Improved animations.
127 |
128 | * Improved documentation.
129 |
130 | ## [0.1.1] - 06.08.2019
131 |
132 | * Improved code style.
133 |
134 | ## [0.1.0] - 06.08.2019
135 |
136 | * Improved Long Press version (still under development).
137 |
138 | * Improved documentation.
139 |
140 | ## [0.0.1] - 05.08.2019
141 |
142 | * Initial release.
143 |
--------------------------------------------------------------------------------
/peek_and_pop/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Ali Yigit Bireroglu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/peek_and_pop/README.md:
--------------------------------------------------------------------------------
1 | # peek_and_pop
2 |
3 | [comment]: <> (Badges)
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | [](https://pub.dev/packages/peek_and_pop)
18 | [](https://github.com/aliyigitbireroglu/flutter-peek-and-pop/blob/master/LICENSE)
19 |
20 | [comment]: <> (Introduction)
21 |
22 |
23 | Peek & Pop implementation for Flutter based on the iOS functionality of the same name.
24 |
25 | **Finally, the v1.0.0 release! More fluent, more optimised and more beautiful than ever. Very customisable and very easy to use.**
26 |
27 | **It is highly recommended to read the documentation and run the example project on a real device to fully understand and inspect the full range of
28 | capabilities.**
29 |
30 | [comment]: <> (ToC)
31 | [Media](#media) | [Description](#description) | [Installation](#installation) | [How-to-Use](#howtouse)
32 |
33 | [comment]: <> (Notice)
34 | ## Notice
35 | * **v0.1.9 and higher no longer requires any modifications to Flutter's normal "binding.dart"! You can leave your Flutter source code alone and happy.**
36 |
37 | * **If you are updating from an earlier version, you can revert your "binding.dart" to its original format.**
38 | * * *
39 | [comment]: <> (Recent)
40 | ## Recent
41 | * **The "Quick Actions" feature is now added. It is highly customisable and you can show a dynamic menu with quick action buttons as the view is
42 | dragged and snapped very easily. The drag and snap limits will be automatically set according to the menu and the view.
43 | [snap](https://pub.dev/packages/snap) is now implemented directly to the package. See [Media](#media) for examples.**
44 |
45 | * **The "Overlap" and "Alignment" features are now added. These two features create a much more fluent Peek & Pop process that is much more similar
46 | to the actual iOS version. See [Media](#media) for examples.**
47 |
48 | * **The "Scale Up" and "Scale Down" features are now added. You can use these features to scale a widget down or up as the Peek & Pop process
49 | proceeds. "Scale Up" is also supported for the "Indicator" feature out of the box.See [Media](#media) for examples.**
50 |
51 | * **Improved enumeration for the stage of the Peek & Pop process.**
52 |
53 | * **The "Indicator" feature is now added. See [Media](#media) for examples.**
54 |
55 | * **Animations are now up to 4x faster with the new optimised blur effect algorithm during the Peek & Pop process.**
56 | * * *
57 | [comment]: <> (Warning)
58 | ## Warning
59 | * **"isHero" is now removed. It wasn't playing well with the package algorithm and it is considered to be unnecessary for the Peek & Pop process.
60 | However, this shouldn't be a problem due to the addition of the new "Overlap" and "Alignment" features. If you must use a Hero widget, only use it
61 | while "willBeDone" or "isDone" is true.**
62 |
63 | * **Old installation instructions are removed. If you wish (for some reason) to use a version older than v0.1.9, see the README of that version for
64 | the relevant installation instructions.**
65 | * * *
66 |
67 |
68 | [comment]: <> (Media)
69 |
70 | ## Media
71 |
72 | Watch on **Youtube**:
73 |
74 | [**v1.0.0 Showcase Demo**](https://youtu.be/IQq_ty5mRYU) | [**v1.0.0 Technical Preview**](https://youtu.be/hIjoWfP0krA)
75 |
76 | [v0.1.7](https://youtu.be/wOWCV7HJzwc)
77 |
78 | [v0.1.0 Mixed](https://youtu.be/G5QLwGtcb1I)
79 |
80 | [v0.0.1 Normal](https://youtu.be/PaEpU31z_7Q) | [v0.0.1 Moveable](https://youtu.be/3TjCFwHoOiE) | [v0.0.1 Platform View](https://youtu.be/489YB-QuJ3k) | [v0.0.1 Hero](https://youtu.be/36DAwnFKSKI)
81 |
82 |
83 |
84 |
85 |
86 |
87 | [comment]: <> (Description)
88 |
89 | ## Description
90 | As a fan of the iOS Peek & Pop functionality, I decided to implement it for Flutter as well.
91 |
92 | The package has been tested on iOS but not yet on Android as I don't have access to an Android device with Force Press capabilities. Help about
93 | this would be appreciated.
94 |
95 | ~~For devices that don't support Force Press, the package comes with an adaptation to Long Press *however* the Long Press version of this package is
96 | still under development and is not yet fully tested so consider it as a developers preview.~~
97 |
98 | (The Long Press version is temporarily removed. It will be added back soon.)
99 |
100 | ##
101 | The power move of this package is what I like to call "Gesture Recognition Rerouting". Normally, when a new widget with GestureDetector or similar
102 | is pushed over an initial widget used for detecting Force Press or when Navigator is used to pop a new page, the user has to restart the gesture
103 | for Flutter to resume updating it. This package fixes that problem as explained in the documentation:
104 |
105 | ```
106 | //This function is called by the instantiated [PeekAndPopChild] once it is ready to be included in the Peek & Pop process. Perhaps the most
107 | //essential functionality of this package also takes places in this function: The gesture recognition is rerouted from the [PeekAndPopDetector]
108 | //to the instantiated [PeekAndPopChild]. This is important for avoiding the necessity of having the user stop and restart their Force Press.
109 | //Instead, the [PeekAndPopController] does this automatically so that the existing Force Press can continue to update even when if
110 | //[PeekAndPopDetector] is blocked by the view which is often the case especially when using PlatformViews.
111 | ```
112 |
113 |
114 | [comment]: <> (Installation)
115 |
116 | ## Installation
117 | *It is easy. Don't worry.*
118 |
119 | **If you do not wish to use PlatformViews you can skip the installation instructions.**
120 |
121 | **Old installation instructions are removed. If you wish (for some reason) to use a version older than v0.1.9, see the README of that version for
122 | the relevant installation instructions.**
123 |
124 | For properly displaying PlatformViews, this package requires the latest Flutter [master](https://github.com/flutter/flutter)
125 | branch. *Maybe* it will work with some other version too but tests made with the [webview_flutter](https://pub.flutter-io.cn/packages/webview_flutter)
126 | seem to only properly display with the latest Flutter [master](https://github.com/flutter/flutter) branch which has improved the PlatformViews that
127 | allow better functionalities such as proper scaling and proper clipping.
128 |
129 | If you do not wish to use PlatformViews, you can skip this step.
130 |
131 | To use latest Flutter [master](https://github.com/flutter/flutter) branch, run the following command.
132 |
133 | **Note**: Don't forget to add io.flutter.embedded_views_previewYES to your Info.plist. See
134 | [webview_flutter](https://pub.flutter-io.cn/packages/webview_flutter) for more info.
135 |
136 | ```
137 | $ git clone -b master https://github.com/flutter/flutter.git
138 | $ flutter channel master
139 | $ flutter upgrade
140 | $ flutter doctor
141 | $ ./flutter/bin/flutter --version
142 | ```
143 |
144 |
145 | [comment]: <> (How-to-Use)
146 |
147 | ## How-to-Use
148 | *Also easy.*
149 |
150 | First of all, as explained in the documentation:
151 |
152 | ```
153 | //I noticed that a fullscreen blur effect via the [BackdropFilter] widget is not good to use while running the animations required for the Peek &
154 | //Pop process as it causes a noticeable drop in the framerate- especially for devices with high resolutions. During a mostly static view, the
155 | //drop is acceptable. However, once the animations start running, this drop causes a visual disturbance. To prevent this, a new optimised blur
156 | //effect algorithm is implemented. Now, the [BackdropFilter] widget is only used until the animations are about to start. At that moment, it is
157 | //replaced by a static image. Therefore, to capture this image, your root CupertinoApp/MaterialApp MUST be wrapped in a [RepaintBoundary] widget
158 | //which uses the [background] key. As a result, the Peek & Pop process is now up to 4x more fluent.
159 | ```
160 |
161 | TL;DR: Wrap your root CupertinoApp/MaterialApp in a RepaintBoundary widget and use the background GlobalKey from "misc.dart".
162 |
163 | This is required for the new optimised blur effect algorithm:
164 |
165 | ```
166 | import 'package:peek_and_pop/misc.dart' as PeekAndPopMisc;
167 |
168 | class MyApp extends StatelessWidget {
169 | @override
170 | Widget build(BuildContext context) {
171 | return RepaintBoundary(
172 | key: PeekAndPopMisc.background,
173 | child: MaterialApp(
174 | title: 'Peek & Pop Demo',
175 | home: MyHomePage(title: 'Peek & Pop Demo')
176 | )
177 | );
178 | }
179 | }
180 | ```
181 |
182 | If you wish to use the "ScaleUp" or the "Scale Down" features, wrap the widgets you wish to scale down or scale up during the Peek & Pop process with
183 | the scaleUpWrapper and scaleDownWrapper functions from "misc.dart":
184 |
185 | ```
186 | @override
187 | Widget build(BuildContext context) {
188 | return Scaffold(
189 | appBar: AppBar(title: Text(widget.title)),
190 | body: PeekAndPopMisc.scaleDownWrapper(
191 | ...,
192 | 0.04,
193 | ),
194 | );
195 | }
196 | ```
197 |
198 | Then, create a PeekAndPopController such as:
199 |
200 | ```
201 | PeekAndPopController(
202 | uiChild(), //Widget uiChild
203 | false, //bool uiChildUseCache
204 | {Key key,
205 | peekAndPopBuilder,
206 | peekAndPopBuilderUseCache,
207 | peekAndPopBuilderAtPeek : peekAndPopBuilderAtPeek,
208 | peekAndPopBuilderAtPop : peekAndPopBuilderAtPop,
209 | quickActionsBuilder : quickActionsBuilder,
210 | sigma : 10,
211 | backdropColor : Colors.black,
212 | alpha : 126,
213 | overlayBuilder : overlayBuilder,
214 | useOverlap : true,
215 | customOverlapRect,
216 | useAlignment, : false,
217 | useIndicator : true,
218 | indicatorScaleUpCoefficient : 0.01,
219 | willPeekAndPopComplete : _willPeekAndPopComplete,
220 | willPushPeekAndPop : _willPushPeekAndPop,
221 | willUpdatePeekAndPop : _willUpdatePeekAndPop,
222 | willCancelPeekAndPop : _willCancelPeekAndPop,
223 | willFinishPeekAndPop : _willFinishPeekAndPop,
224 | willClosePeekAndPop : _willClosePeekAndPop,
225 | onPeekAndPopComplete : _onPeekAndPopComplete,
226 | onPushPeekAndPop : _onPushPeekAndPop,
227 | onUpdatePeekAndPop : _onUpdatePeekAndPop,
228 | onCancelPeekAndPop : _onCancelPeekAndPop,
229 | onFinishPeekAndPop : _onFinishPeekAndPop,
230 | onClosePeekAndPop : _onFinishPeekAndPop,
231 | onPressStart : _onPressStart,
232 | onPressUpdate : _onPressUpdate,
233 | onPressEnd : _onPressEnd,
234 | treshold : 0.5,
235 | startPressure : 0.125,
236 | peakPressure : 1.0,
237 | peekScale : 0.5,
238 | peekCoefficient : 0.05,
239 | popTransition,
240 | useHaptics : true})
241 |
242 | Widget uiChild() {}
243 |
244 | Widget peekAndPopBuilderAtPeek(BuildContext context, PeekAndPopControllerState _peekAndPopController);
245 | Widget peekAndPopBuilderAtPop(BuildContext context, PeekAndPopControllerState _peekAndPopController);
246 |
247 | QuickActionsData quickActionsBuilder(PeekAndPopControllerState _peekAndPopController);
248 |
249 | WidgetBuilder overlayBuiler(BuildContext context);
250 |
251 | bool _willPeekAndPopComplete(PeekAndPopControllerState _peekAndPopController);
252 | bool _willPushPeekAndPop(PeekAndPopControllerState _peekAndPopController);
253 | bool _willUpdatePeekAndPop(PeekAndPopControllerState _peekAndPopController);
254 | bool _willCancelPeekAndPop(PeekAndPopControllerState _peekAndPopController);
255 | bool _willFinishPeekAndPop(PeekAndPopControllerState _peekAndPopController);
256 | bool _willClosePeekAndPop(PeekAndPopControllerState _peekAndPopController);
257 |
258 | void _onPeekAndPopComplete(PeekAndPopControllerState _peekAndPopController);
259 | void _onPushPeekAndPop(PeekAndPopControllerState _peekAndPopController);
260 | void _onUpdatePeekAndPop(PeekAndPopControllerState _peekAndPopController);
261 | void _onCancelPeekAndPop(PeekAndPopControllerState _peekAndPopController);
262 | void _onFinishPeekAndPop(PeekAndPopControllerState _peekAndPopController);
263 | void _onClosePeekAndPop(PeekAndPopControllerState _peekAndPopController);
264 |
265 | void _onPressStart(dynamic dragDetails);
266 | void _onPressUpdate(dynamic dragDetails);
267 | void _onPressEnd(dynamic dragDetails);
268 |
269 | ```
270 |
271 | **Further Explanations:**
272 |
273 | *For a complete set of descriptions for all parameters and methods, see the [documentation](https://pub.dev/documentation/peek_and_pop/latest/).*
274 |
275 | * Set [uiChildUseCache] to true if your [uiChild] doesn't change during the Peek & Pop process.
276 | * Set [peekAndPopBuilderUseCache] to true if your [peekAndPopBuilder] doesn't change during the Peek & Pop process.
277 | * If [peekAndPopBuilderAtPop] and [peekAndPopBuilderAtPeek] are set, [peekAndPopBuilder] and [peekAndPopBuilderUseCache] are ignored.
278 | * If one of [peekAndPopBuilderAtPop] and [peekAndPopBuilderAtPeek] is set, the other one must be set too.
279 | * If [quickActionsBuilder] is set, it is recommended that [peekAndPopBuilderAtPop] and [peekAndPopBuilderAtPop] are set too.
280 | * [overlayBuilder] is an optional second view to be displayed during the Peek & Pop process. This entire widget is built after everything else.
281 | * For all [PeekAndPopProcessNotifier] callbacks such as [willPeekAndPopComplete], you can return false to prevent the default action.
282 | * All [PeekAndPopProcessNotifier] and [PeekAndPopProcessCallback] callbacks will return a reference to the created [PeekAndPopController] state.
283 | You can save this instance for further actions.
284 | * [pageTransition] is the transition to be used when the view is opened directly or when the view is closed. A default [SlideTransition] is provided.
285 | * Use [PeekAndPopControllerState]'s [void closePeekAndPop()] method to close the Peek & Pop process. Do not call [Navigator.of(context).pop()]
286 | directly.
287 | * Use [PeekAndPopControllerState]'s [stage] variable to get enumeration for the stage of the Peek & Pop process. If you want to only know when the
288 | Peek & Pop process will be or is completed, you can also use [willBeDone] or [isDone] variables.
289 |
290 |
291 | [comment]: <> (Notes)
292 | ## Notes
293 | I started using and learning Flutter only some weeks ago so this package might have some parts that don't make sense, that should be completely
294 | different, that could be much better, etc. Please let me know! Nicely!
295 |
296 | Any help, suggestion or criticism is appreciated!
297 |
298 | Cheers.
299 |
300 | [comment]: <> (CosmosSoftware)
301 |
302 |
303 |
--------------------------------------------------------------------------------
/peek_and_pop/example/.flutter-plugins-dependencies:
--------------------------------------------------------------------------------
1 | {"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"webview_flutter","path":"/Users/fabriziotognetto/Library/flutter/.pub-cache/hosted/pub.dartlang.org/webview_flutter-0.3.13/","dependencies":[]}],"android":[{"name":"webview_flutter","path":"/Users/fabriziotognetto/Library/flutter/.pub-cache/hosted/pub.dartlang.org/webview_flutter-0.3.13/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"webview_flutter","dependencies":[]}],"date_created":"2020-09-23 23:12:06.440462","version":"1.22.0-12.1.pre"}
--------------------------------------------------------------------------------
/peek_and_pop/example/.gitignore:
--------------------------------------------------------------------------------
1 | /gitignore
2 | /android
3 | /build
4 | /ios
5 | .notes.md
6 | .notes.txt
7 |
8 | # Miscellaneous
9 | *.class
10 | *.log
11 | *.pyc
12 | *.swp
13 | .DS_Store
14 | .atom/
15 | .buildlog/
16 | .history
17 | .svn/
18 |
19 | # IntelliJ related
20 | *.iml
21 | *.ipr
22 | *.iws
23 | .idea/
24 |
25 | # The .vscode folder contains launch configuration and tasks you configure in
26 | # VS Code which you may wish to be included in version control, so this line
27 | # is commented out by default.
28 | #.vscode/
29 |
30 | # Flutter/Dart/Pub related
31 | **/doc/api/
32 | .dart_tool/
33 | .flutter-plugins
34 | .packages
35 | .pub-cache/
36 | .pub/
37 | build/
38 |
39 | # Android related
40 | **/android/**/gradle-wrapper.jar
41 | **/android/.gradle
42 | **/android/captures/
43 | **/android/gradlew
44 | **/android/gradlew.bat
45 | **/android/local.properties
46 | **/android/**/GeneratedPluginRegistrant.java
47 |
48 | # iOS/XCode related
49 | **/ios/**/*.mode1v3
50 | **/ios/**/*.mode2v3
51 | **/ios/**/*.moved-aside
52 | **/ios/**/*.pbxuser
53 | **/ios/**/*.perspectivev3
54 | **/ios/**/*sync/
55 | **/ios/**/.sconsign.dblite
56 | **/ios/**/.tags*
57 | **/ios/**/.vagrant/
58 | **/ios/**/DerivedData/
59 | **/ios/**/Icon?
60 | **/ios/**/Pods/
61 | **/ios/**/.symlinks/
62 | **/ios/**/profile
63 | **/ios/**/xcuserdata
64 | **/ios/.generated/
65 | **/ios/Flutter/App.framework
66 | **/ios/Flutter/Flutter.framework
67 | **/ios/Flutter/Generated.xcconfig
68 | **/ios/Flutter/app.flx
69 | **/ios/Flutter/app.zip
70 | **/ios/Flutter/flutter_assets/
71 | **/ios/ServiceDefinitions.json
72 | **/ios/Runner/GeneratedPluginRegistrant.*
73 |
74 | # Exceptions to above rules.
75 | !**/ios/**/default.mode1v3
76 | !**/ios/**/default.mode2v3
77 | !**/ios/**/default.pbxuser
78 | !**/ios/**/default.perspectivev3
79 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
80 |
--------------------------------------------------------------------------------
/peek_and_pop/example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 20e59316b8b8474554b38493b8ca888794b0234a
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/peek_and_pop/example/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [1.0.3] - 21.11.2019
2 |
3 | * Minor changes.
4 |
5 | ## [1.0.2] - 07.09.2019
6 |
7 | * Two new PeekAndPopBuilders are added to [PeekAndPopController]. Use [PeekAndPopController.peekAndPopBuilderAtPeek] and
8 | [PeekAndPopController.peekAndPopBuilderAtPop] for both convenience and improved performance.
9 |
10 | * Improved performance.
11 |
12 | * [1.0.2+1] Support for latest dependencies.
13 |
14 | ## [1.0.1] - 03.09.2019
15 |
16 | * Minor changes.
17 |
18 | ## [1.0.0] - 30.08.2019
19 |
20 | * The "Quick Actions" feature is now added. It is highly customisable and you can show a dynamic menu with quick action buttons as the view is
21 | dragged and snapped very easily. The drag and snap limits will be automatically set according to the menu and the view.
22 | [snap](https://pub.dev/packages/snap) is now implemented directly to the package. See this [video](https://youtu.be/IQq_ty5mRYU) for examples.
23 |
24 | * The "Overlap" and "Alignment" features are now added. These two features create a much more fluent Peek & Pop process that is much more similar
25 | to the actual iOS version. See this [video](https://youtu.be/IQq_ty5mRYU) for examples.
26 |
27 | * The "Scale Up" and "Scale Down" features are now added. You can use these features to scale a widget down or up as the Peek & Pop process
28 | proceeds. "Scale Up" is also supported for the "Indicator" feature out of the box. See this [video](https://youtu.be/IQq_ty5mRYU) for examples.
29 |
30 | * "isHero" is now removed. It wasn't playing well with the package algorithm and it is considered to be unnecessary for the Peek & Pop process.
31 | However, this shouldn't be a problem due to the addition of the new "Overlap" and "Alignment" features. If you must use a Hero widget, only use it
32 | while "willBeDone" or "isDone" is true.
33 |
34 | * A workaround is implemented to avoid a Flutter Engine bug that was causing trouble with the optimised blur effect algorithm.
35 |
36 | * Improved enumeration for the stage of the Peek & Pop process.
37 |
38 | * Improved performance.
39 |
40 | * Fine tuning.
41 |
42 | * Improved code style.
43 |
44 | * Improved example project.
45 |
46 | * Updated README.
47 |
48 | * Old installation instructions are removed. If you wish (for some reason) to use a version older than v0.1.9, see the README of that version for
49 | the relevant installation instructions.
50 |
51 | ## [0.2.0] - 23.08.2019
52 |
53 | * Improved performance.
54 |
55 | * Minor changes.
56 |
57 | * Improved code style with trailing commas.
58 |
59 | * [0.2.0+1] Minor changes.
60 |
61 | ## [0.1.9] - 20.08.2019
62 |
63 | * Modifications to Flutter's normal "binding.dart" are no longer required!
64 |
65 | * The Long Press version is temporarily removed. It will be added back soon.
66 |
67 | * Code excerpt added to the README.
68 |
69 | * Updated README.
70 |
71 | * [0.1.9+1] Updated README.
72 |
73 | ## [0.1.8] - 18.08.2019
74 |
75 | * Example project adapted to the updated [snap](https://pub.dev/packages/snap).
76 |
77 | * Minor changes.
78 |
79 | * [0.1.8+1] Updated README.
80 |
81 | ## [0.1.7] - 14.08.2019
82 |
83 | * The "Indicator" feature added. See this [video](https://youtu.be/wOWCV7HJzwc) for examples.
84 |
85 | * Improved performance.
86 |
87 | * Fine tuning.
88 |
89 | ## [0.1.6] - 12.08.2019
90 |
91 | * Improved Long Press version (still under development).
92 |
93 | * Fine tuning.
94 |
95 | * Improved documentation.
96 |
97 | * Updated README.
98 |
99 | ## [0.1.5] - 11.08.2019
100 |
101 | * Improved performance.
102 |
103 | * Improved code style.
104 |
105 | ## [0.1.4] - 11.08.2019
106 |
107 | * A minor bug is fixed.
108 |
109 | ## [0.1.3] - 07.08.2019
110 |
111 | * A minor bug in the example project is fixed.
112 |
113 | * Updated README:
114 |
115 | **Note**: Don't forget to add io.flutter.embedded_views_previewYES to your Info.plist. See
116 | [webview_flutter](https://pub.flutter-io.cn/packages/webview_flutter) for more info.
117 |
118 | ## [0.1.2] - 07.08.2019
119 |
120 | * [snap](https://pub.dev/packages/snap) is now implemented directly to the example.
121 |
122 | * More callbacks added for better control.
123 |
124 | * Simple enumeration for the stage of the Peek & Pop process added.
125 |
126 | * Improved animations.
127 |
128 | * Improved documentation.
129 |
130 | ## [0.1.1] - 06.08.2019
131 |
132 | * Improved code style.
133 |
134 | ## [0.1.0] - 06.08.2019
135 |
136 | * Improved Long Press version (still under development).
137 |
138 | * Improved documentation.
139 |
140 | ## [0.0.1] - 05.08.2019
141 |
142 | * Initial release.
143 |
--------------------------------------------------------------------------------
/peek_and_pop/example/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Ali Yigit Bireroglu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/peek_and_pop/example/README.md:
--------------------------------------------------------------------------------
1 | # example
2 |
3 | Example Project for peek_and_pop.
4 |
5 | Note: Don't forget to add io.flutter.embedded_views_previewYES to your Info.plist. See
6 | [webview_flutter](https://pub.flutter-io.cn/packages/webview_flutter) for more info.
7 |
8 |
9 | # peek_and_pop
10 |
11 | [comment]: <> (Badges)
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | [](https://pub.dev/packages/peek_and_pop)
26 | [](https://github.com/aliyigitbireroglu/flutter-peek-and-pop/blob/master/LICENSE)
27 |
28 | [comment]: <> (Introduction)
29 |
30 |
31 | Peek & Pop implementation for Flutter based on the iOS functionality of the same name.
32 |
33 | **Finally, the v1.0.0 release! More fluent, more optimised and more beautiful than ever. Very customisable and very easy to use.**
34 |
35 | **It is highly recommended to read the documentation and run the example project on a real device to fully understand and inspect the full range of
36 | capabilities.**
37 |
38 | [comment]: <> (ToC)
39 | [Media](#media) | [Description](#description) | [Installation](#installation) | [How-to-Use](#howtouse)
40 |
41 | [comment]: <> (Notice)
42 | ## Notice
43 | * **v0.1.9 and higher no longer requires any modifications to Flutter's normal "binding.dart"! You can leave your Flutter source code alone and happy.**
44 |
45 | * **If you are updating from an earlier version, you can revert your "binding.dart" to its original format.**
46 | * * *
47 | [comment]: <> (Recent)
48 | ## Recent
49 | * **The "Quick Actions" feature is now added. It is highly customisable and you can show a dynamic menu with quick action buttons as the view is
50 | dragged and snapped very easily. The drag and snap limits will be automatically set according to the menu and the view.
51 | [snap](https://pub.dev/packages/snap) is now implemented directly to the package. See [Media](#media) for examples.**
52 |
53 | * **The "Overlap" and "Alignment" features are now added. These two features create a much more fluent Peek & Pop process that is much more similar
54 | to the actual iOS version. See [Media](#media) for examples.**
55 |
56 | * **The "Scale Up" and "Scale Down" features are now added. You can use these features to scale a widget down or up as the Peek & Pop process
57 | proceeds. "Scale Up" is also supported for the "Indicator" feature out of the box.See [Media](#media) for examples.**
58 |
59 | * **Improved enumeration for the stage of the Peek & Pop process.**
60 |
61 | * **The "Indicator" feature is now added. See [Media](#media) for examples.**
62 |
63 | * **Animations are now up to 4x faster with the new optimised blur effect algorithm during the Peek & Pop process.**
64 | * * *
65 | [comment]: <> (Warning)
66 | ## Warning
67 | * **"isHero" is now removed. It wasn't playing well with the package algorithm and it is considered to be unnecessary for the Peek & Pop process.
68 | However, this shouldn't be a problem due to the addition of the new "Overlap" and "Alignment" features. If you must use a Hero widget, only use it
69 | while "willBeDone" or "isDone" is true.**
70 |
71 | * **Old installation instructions are removed. If you wish (for some reason) to use a version older than v0.1.9, see the README of that version for
72 | the relevant installation instructions.**
73 | * * *
74 |
75 |
76 | [comment]: <> (Media)
77 |
78 | ## Media
79 |
80 | Watch on **Youtube**:
81 |
82 | [**v1.0.0 Showcase Demo**](https://youtu.be/IQq_ty5mRYU) | [**v1.0.0 Technical Preview**](https://youtu.be/hIjoWfP0krA)
83 |
84 | [v0.1.7](https://youtu.be/wOWCV7HJzwc)
85 |
86 | [v0.1.0 Mixed](https://youtu.be/G5QLwGtcb1I)
87 |
88 | [v0.0.1 Normal](https://youtu.be/PaEpU31z_7Q) | [v0.0.1 Moveable](https://youtu.be/3TjCFwHoOiE) | [v0.0.1 Platform View](https://youtu.be/489YB-QuJ3k) | [v0.0.1 Hero](https://youtu.be/36DAwnFKSKI)
89 |
90 |
91 |
92 |
93 |
94 |
95 | [comment]: <> (Description)
96 |
97 | ## Description
98 | As a fan of the iOS Peek & Pop functionality, I decided to implement it for Flutter as well.
99 |
100 | The package has been tested on iOS but not yet on Android as I don't have access to an Android device with Force Press capabilities. Help about
101 | this would be appreciated.
102 |
103 | ~~For devices that don't support Force Press, the package comes with an adaptation to Long Press *however* the Long Press version of this package is
104 | still under development and is not yet fully tested so consider it as a developers preview.~~
105 |
106 | (The Long Press version is temporarily removed. It will be added back soon.)
107 |
108 | ##
109 | The power move of this package is what I like to call "Gesture Recognition Rerouting". Normally, when a new widget with GestureDetector or similar
110 | is pushed over an initial widget used for detecting Force Press or when Navigator is used to pop a new page, the user has to restart the gesture
111 | for Flutter to resume updating it. This package fixes that problem as explained in the documentation:
112 |
113 | ```
114 | //This function is called by the instantiated [PeekAndPopChild] once it is ready to be included in the Peek & Pop process. Perhaps the most
115 | //essential functionality of this package also takes places in this function: The gesture recognition is rerouted from the [PeekAndPopDetector]
116 | //to the instantiated [PeekAndPopChild]. This is important for avoiding the necessity of having the user stop and restart their Force Press.
117 | //Instead, the [PeekAndPopController] does this automatically so that the existing Force Press can continue to update even when if
118 | //[PeekAndPopDetector] is blocked by the view which is often the case especially when using PlatformViews.
119 | ```
120 |
121 |
122 | [comment]: <> (Installation)
123 |
124 | ## Installation
125 | *It is easy. Don't worry.*
126 |
127 | **If you do not wish to use PlatformViews you can skip the installation instructions.**
128 |
129 | **Old installation instructions are removed. If you wish (for some reason) to use a version older than v0.1.9, see the README of that version for
130 | the relevant installation instructions.**
131 |
132 | For properly displaying PlatformViews, this package requires the latest Flutter [master](https://github.com/flutter/flutter)
133 | branch. *Maybe* it will work with some other version too but tests made with the [webview_flutter](https://pub.flutter-io.cn/packages/webview_flutter)
134 | seem to only properly display with the latest Flutter [master](https://github.com/flutter/flutter) branch which has improved the PlatformViews that
135 | allow better functionalities such as proper scaling and proper clipping.
136 |
137 | If you do not wish to use PlatformViews, you can skip this step.
138 |
139 | To use latest Flutter [master](https://github.com/flutter/flutter) branch, run the following command.
140 |
141 | **Note**: Don't forget to add io.flutter.embedded_views_previewYES to your Info.plist. See
142 | [webview_flutter](https://pub.flutter-io.cn/packages/webview_flutter) for more info.
143 |
144 | ```
145 | $ git clone -b master https://github.com/flutter/flutter.git
146 | $ flutter channel master
147 | $ flutter upgrade
148 | $ flutter doctor
149 | $ ./flutter/bin/flutter --version
150 | ```
151 |
152 |
153 | [comment]: <> (How-to-Use)
154 |
155 | ## How-to-Use
156 | *Also easy.*
157 |
158 | First of all, as explained in the documentation:
159 |
160 | ```
161 | //I noticed that a fullscreen blur effect via the [BackdropFilter] widget is not good to use while running the animations required for the Peek &
162 | //Pop process as it causes a noticeable drop in the framerate- especially for devices with high resolutions. During a mostly static view, the
163 | //drop is acceptable. However, once the animations start running, this drop causes a visual disturbance. To prevent this, a new optimised blur
164 | //effect algorithm is implemented. Now, the [BackdropFilter] widget is only used until the animations are about to start. At that moment, it is
165 | //replaced by a static image. Therefore, to capture this image, your root CupertinoApp/MaterialApp MUST be wrapped in a [RepaintBoundary] widget
166 | //which uses the [background] key. As a result, the Peek & Pop process is now up to 4x more fluent.
167 | ```
168 |
169 | TL;DR: Wrap your root CupertinoApp/MaterialApp in a RepaintBoundary widget and use the background GlobalKey from "misc.dart".
170 |
171 | This is required for the new optimised blur effect algorithm:
172 |
173 | ```
174 | import 'package:peek_and_pop/misc.dart' as PeekAndPopMisc;
175 |
176 | class MyApp extends StatelessWidget {
177 | @override
178 | Widget build(BuildContext context) {
179 | return RepaintBoundary(
180 | key: PeekAndPopMisc.background,
181 | child: MaterialApp(
182 | title: 'Peek & Pop Demo',
183 | home: MyHomePage(title: 'Peek & Pop Demo')
184 | )
185 | );
186 | }
187 | }
188 | ```
189 |
190 | If you wish to use the "ScaleUp" or the "Scale Down" features, wrap the widgets you wish to scale down or scale up during the Peek & Pop process with
191 | the scaleUpWrapper and scaleDownWrapper functions from "misc.dart":
192 |
193 | ```
194 | @override
195 | Widget build(BuildContext context) {
196 | return Scaffold(
197 | appBar: AppBar(title: Text(widget.title)),
198 | body: PeekAndPopMisc.scaleDownWrapper(
199 | ...,
200 | 0.04,
201 | ),
202 | );
203 | }
204 | ```
205 |
206 | Then, create a PeekAndPopController such as:
207 |
208 | ```
209 | PeekAndPopController(
210 | uiChild(), //Widget uiChild
211 | false, //bool uiChildUseCache
212 | {Key key,
213 | peekAndPopBuilder,
214 | peekAndPopBuilderUseCache,
215 | peekAndPopBuilderAtPeek : peekAndPopBuilderAtPeek,
216 | peekAndPopBuilderAtPop : peekAndPopBuilderAtPop,
217 | quickActionsBuilder : quickActionsBuilder,
218 | sigma : 10,
219 | backdropColor : Colors.black,
220 | alpha : 126,
221 | overlayBuilder : overlayBuilder,
222 | useOverlap : true,
223 | customOverlapRect,
224 | useAlignment, : false,
225 | useIndicator : true,
226 | indicatorScaleUpCoefficient : 0.01,
227 | willPeekAndPopComplete : _willPeekAndPopComplete,
228 | willPushPeekAndPop : _willPushPeekAndPop,
229 | willUpdatePeekAndPop : _willUpdatePeekAndPop,
230 | willCancelPeekAndPop : _willCancelPeekAndPop,
231 | willFinishPeekAndPop : _willFinishPeekAndPop,
232 | willClosePeekAndPop : _willClosePeekAndPop,
233 | onPeekAndPopComplete : _onPeekAndPopComplete,
234 | onPushPeekAndPop : _onPushPeekAndPop,
235 | onUpdatePeekAndPop : _onUpdatePeekAndPop,
236 | onCancelPeekAndPop : _onCancelPeekAndPop,
237 | onFinishPeekAndPop : _onFinishPeekAndPop,
238 | onClosePeekAndPop : _onFinishPeekAndPop,
239 | onPressStart : _onPressStart,
240 | onPressUpdate : _onPressUpdate,
241 | onPressEnd : _onPressEnd,
242 | treshold : 0.5,
243 | startPressure : 0.125,
244 | peakPressure : 1.0,
245 | peekScale : 0.5,
246 | peekCoefficient : 0.05,
247 | popTransition,
248 | useHaptics : true})
249 |
250 | Widget uiChild() {}
251 |
252 | Widget peekAndPopBuilderAtPeek(BuildContext context, PeekAndPopControllerState _peekAndPopController);
253 | Widget peekAndPopBuilderAtPop(BuildContext context, PeekAndPopControllerState _peekAndPopController);
254 |
255 | QuickActionsData quickActionsBuilder(PeekAndPopControllerState _peekAndPopController);
256 |
257 | WidgetBuilder overlayBuiler(BuildContext context);
258 |
259 | bool _willPeekAndPopComplete(PeekAndPopControllerState _peekAndPopController);
260 | bool _willPushPeekAndPop(PeekAndPopControllerState _peekAndPopController);
261 | bool _willUpdatePeekAndPop(PeekAndPopControllerState _peekAndPopController);
262 | bool _willCancelPeekAndPop(PeekAndPopControllerState _peekAndPopController);
263 | bool _willFinishPeekAndPop(PeekAndPopControllerState _peekAndPopController);
264 | bool _willClosePeekAndPop(PeekAndPopControllerState _peekAndPopController);
265 |
266 | void _onPeekAndPopComplete(PeekAndPopControllerState _peekAndPopController);
267 | void _onPushPeekAndPop(PeekAndPopControllerState _peekAndPopController);
268 | void _onUpdatePeekAndPop(PeekAndPopControllerState _peekAndPopController);
269 | void _onCancelPeekAndPop(PeekAndPopControllerState _peekAndPopController);
270 | void _onFinishPeekAndPop(PeekAndPopControllerState _peekAndPopController);
271 | void _onClosePeekAndPop(PeekAndPopControllerState _peekAndPopController);
272 |
273 | void _onPressStart(dynamic dragDetails);
274 | void _onPressUpdate(dynamic dragDetails);
275 | void _onPressEnd(dynamic dragDetails);
276 |
277 | ```
278 |
279 | **Further Explanations:**
280 |
281 | *For a complete set of descriptions for all parameters and methods, see the [documentation](https://pub.dev/documentation/peek_and_pop/latest/).*
282 |
283 | * Set [uiChildUseCache] to true if your [uiChild] doesn't change during the Peek & Pop process.
284 | * Set [peekAndPopBuilderUseCache] to true if your [peekAndPopBuilder] doesn't change during the Peek & Pop process.
285 | * If [peekAndPopBuilderAtPop] and [peekAndPopBuilderAtPeek] are set, [peekAndPopBuilder] and [peekAndPopBuilderUseCache] are ignored.
286 | * If one of [peekAndPopBuilderAtPop] and [peekAndPopBuilderAtPeek] is set, the other one must be set too.
287 | * If [quickActionsBuilder] is set, it is recommended that [peekAndPopBuilderAtPop] and [peekAndPopBuilderAtPop] are set too.
288 | * [overlayBuilder] is an optional second view to be displayed during the Peek & Pop process. This entire widget is built after everything else.
289 | * For all [PeekAndPopProcessNotifier] callbacks such as [willPeekAndPopComplete], you can return false to prevent the default action.
290 | * All [PeekAndPopProcessNotifier] and [PeekAndPopProcessCallback] callbacks will return a reference to the created [PeekAndPopController] state.
291 | You can save this instance for further actions.
292 | * [pageTransition] is the transition to be used when the view is opened directly or when the view is closed. A default [SlideTransition] is provided.
293 | * Use [PeekAndPopControllerState]'s [void closePeekAndPop()] method to close the Peek & Pop process. Do not call [Navigator.of(context).pop()]
294 | directly.
295 | * Use [PeekAndPopControllerState]'s [stage] variable to get enumeration for the stage of the Peek & Pop process. If you want to only know when the
296 | Peek & Pop process will be or is completed, you can also use [willBeDone] or [isDone] variables.
297 |
298 |
299 | [comment]: <> (Notes)
300 | ## Notes
301 | I started using and learning Flutter only some weeks ago so this package might have some parts that don't make sense, that should be completely
302 | different, that could be much better, etc. Please let me know! Nicely!
303 |
304 | Any help, suggestion or criticism is appreciated!
305 |
306 | Cheers.
307 |
308 | [comment]: <> (CosmosSoftware)
309 |
310 |
311 |
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/0.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/1.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/10.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/10.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/11.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/11.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/12.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/12.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/13.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/13.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/14.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/14.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/15.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/15.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/16.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/16.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/17.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/17.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/18.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/18.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/19.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/19.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/2.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/20.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/20.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/21.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/21.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/22.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/22.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/23.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/23.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/24.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/24.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/25.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/25.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/26.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/26.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/27.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/27.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/28.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/28.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/29.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/29.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/3.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/4.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/5.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/5.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/6.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/6.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/7.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/7.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/8.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/8.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/9.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/9.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/Hero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/Hero.png
--------------------------------------------------------------------------------
/peek_and_pop/example/assets/Scenery.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/assets/Scenery.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | //Note: Don't forget to add io.flutter.embedded_views_previewYES to your Info.plist. See
2 | //[webview_flutter](https://pub.flutter-io.cn/packages/webview_flutter) for more info.
3 |
4 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5 | // © Cosmos Software | Ali Yigit Bireroglu /
6 | // All material used in the making of this code, project, program, application, software et cetera (the "Intellectual Property") /
7 | // belongs completely and solely to Ali Yigit Bireroglu. This includes but is not limited to the source code, the multimedia and /
8 | // other asset files. If you were granted this Intellectual Property for personal use, you are obligated to include this copyright /
9 | // text at all times. /
10 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11 | //@formatter:off
12 |
13 | import 'package:flutter/foundation.dart';
14 | import 'package:flutter/cupertino.dart';
15 | import 'package:flutter/material.dart';
16 | import 'package:flutter/services.dart';
17 |
18 | import 'package:webview_flutter/webview_flutter.dart';
19 | import 'nav_bar.dart' as MyNavBar;
20 |
21 | import 'package:peek_and_pop/peek_and_pop.dart';
22 | import 'package:peek_and_pop/misc.dart' as PeekAndPopMisc;
23 |
24 | PeekAndPopControllerState peekAndPopController;
25 |
26 | final GlobalKey scaffold = GlobalKey();
27 | final GlobalKey header = GlobalKey();
28 |
29 | void main() => runApp(MyApp());
30 |
31 | class MyApp extends StatelessWidget {
32 | @override
33 | Widget build(BuildContext context) {
34 | return RepaintBoundary(
35 | key: PeekAndPopMisc.background,
36 | child: MaterialApp(
37 | title: 'Peek & Pop Demo',
38 | theme: ThemeData(primarySwatch: Colors.blue),
39 | home: MyHomePage(title: 'Peek & Pop Demo'),
40 | ),
41 | );
42 | }
43 | }
44 |
45 | class MyHomePage extends StatefulWidget {
46 | MyHomePage({Key key, this.title}) : super(key: key);
47 |
48 | final String title;
49 |
50 | @override
51 | _MyHomePageState createState() => _MyHomePageState();
52 | }
53 |
54 | class _MyHomePageState extends State {
55 | void onPushPeekAndPop(PeekAndPopControllerState _peekAndPopController) {
56 | peekAndPopController = _peekAndPopController;
57 | }
58 |
59 | void showSnackbar() {
60 | scaffold.currentState.showSnackBar(SnackBar(content: const Text("Everything works as usual.")));
61 | }
62 |
63 | Widget paddingWrapper(Widget child) {
64 | return Container(
65 | color: Colors.transparent,
66 | child: Padding(
67 | padding: EdgeInsets.all(25),
68 | child: child,
69 | ),
70 | );
71 | }
72 |
73 | Widget atPeekWrapper(Widget child, PeekAndPopControllerState _peekAndPopController) {
74 | return Container(
75 | decoration: BoxDecoration(
76 | borderRadius: const BorderRadius.all(const Radius.circular(10.0)),
77 | boxShadow: [
78 | const BoxShadow(
79 | color: Colors.black,
80 | offset: const Offset(0, 15),
81 | spreadRadius: -5,
82 | blurRadius: 20,
83 | ),
84 | ],
85 | ),
86 | child: ClipRRect(
87 | borderRadius: const BorderRadius.all(const Radius.circular(10.0)),
88 | child: child,
89 | ),
90 | );
91 | }
92 |
93 | MyNavBar.CupertinoNavigationBar appBar(PeekAndPopControllerState _peekAndPopController) {
94 | return MyNavBar.CupertinoNavigationBar(
95 | key: header,
96 | backgroundColor: const Color(0xff1B1B1B),
97 | border: const Border(
98 | bottom: const BorderSide(
99 | color: Colors.black,
100 | width: 0.0,
101 | style: BorderStyle.solid,
102 | ),
103 | ),
104 | middle: const Text(
105 | "Peek & Pop",
106 | style: const TextStyle(color: const Color(0xffFF9500)),
107 | ),
108 | leading: CupertinoButton(
109 | padding: EdgeInsets.only(bottom: 2),
110 | onPressed: () {
111 | HapticFeedback.mediumImpact();
112 | _peekAndPopController.closePeekAndPop();
113 | },
114 | child: const Icon(
115 | CupertinoIcons.left_chevron,
116 | size: 25,
117 | color: const Color(0xffFF9500),
118 | ),
119 | ),
120 | trailing: CupertinoButton(
121 | padding: EdgeInsets.only(bottom: 2),
122 | onPressed: () {
123 | HapticFeedback.mediumImpact();
124 | showSnackbar();
125 | },
126 | child: const Icon(
127 | CupertinoIcons.heart_solid,
128 | size: 25,
129 | color: const Color(0xffFF9500),
130 | ),
131 | ),
132 | transitionBetweenRoutes: false,
133 | );
134 | }
135 |
136 | Widget atPopWrapper(Widget child, PeekAndPopControllerState _peekAndPopController) {
137 | return Scaffold(
138 | key: scaffold,
139 | appBar: appBar(_peekAndPopController),
140 | body: SizedBox.expand(child: child),
141 | );
142 | }
143 |
144 | Widget normalRow(String text, Color color) {
145 | return Container(
146 | constraints: BoxConstraints.expand(),
147 | decoration: BoxDecoration(
148 | color: color,
149 | borderRadius: const BorderRadius.all(const Radius.circular(10.0)),
150 | ),
151 | child: Center(
152 | child: Text(
153 | text,
154 | style: const TextStyle(
155 | color: Colors.white,
156 | fontWeight: FontWeight.bold,
157 | fontSize: 25,
158 | ),
159 | textAlign: TextAlign.center,
160 | ),
161 | ),
162 | );
163 | }
164 |
165 | Widget specialRow(String text, Color color) {
166 | return Container(
167 | constraints: BoxConstraints.expand(),
168 | decoration: BoxDecoration(
169 | color: color,
170 | borderRadius: const BorderRadius.all(const Radius.circular(10.0)),
171 | ),
172 | child: Center(
173 | child: Padding(
174 | padding: EdgeInsets.all(25),
175 | child: Hero(
176 | tag: "Hero",
177 | child: Image.asset(
178 | "assets/Hero.png",
179 | fit: BoxFit.contain,
180 | key: Key("Image"),
181 | ),
182 | ),
183 | ),
184 | ),
185 | );
186 | }
187 |
188 | Widget normalPeekAndPopBuilderAtPeek(BuildContext context, PeekAndPopControllerState _peekAndPopController) {
189 | return atPeekWrapper(
190 | Image.asset(
191 | "assets/Scenery.jpeg",
192 | fit: BoxFit.contain,
193 | key: Key("Image"),
194 | ),
195 | _peekAndPopController,
196 | );
197 | }
198 |
199 | Widget normalPeekAndPopBuilderAtPop(BuildContext context, PeekAndPopControllerState _peekAndPopController) {
200 | return atPopWrapper(
201 | Transform.translate(
202 | offset: Offset(0, -50),
203 | child: Image.asset(
204 | "assets/Scenery.jpeg",
205 | fit: BoxFit.contain,
206 | key: Key("Image"),
207 | ),
208 | ),
209 | _peekAndPopController,
210 | );
211 | }
212 |
213 | Widget platformViewPeekAndPopBuilder(BuildContext context, PeekAndPopControllerState _peekAndPopController) {
214 | return Container(
215 | decoration: BoxDecoration(
216 | borderRadius: (_peekAndPopController.willBeDone || _peekAndPopController.isDone) ? null : const BorderRadius.all(const Radius.circular(10.0)),
217 | boxShadow: (_peekAndPopController.willBeDone || _peekAndPopController.isDone)
218 | ? null
219 | : [
220 | const BoxShadow(
221 | color: Colors.black,
222 | offset: const Offset(0, 15),
223 | spreadRadius: -5,
224 | blurRadius: 20,
225 | ),
226 | ],
227 | ),
228 | child: ClipRRect(
229 | borderRadius: BorderRadius.all((_peekAndPopController.willBeDone || _peekAndPopController.isDone) ? const Radius.circular(0.0) : const Radius.circular(10.0)),
230 | child: Scaffold(
231 | key: scaffold,
232 | appBar: (_peekAndPopController.willBeDone || _peekAndPopController.isDone) ? appBar(_peekAndPopController) : null,
233 | body: SizedBox.expand(
234 | child: (peekAndPopController.stage == Stage.IsPeeking || _peekAndPopController.willBeDone || peekAndPopController.isDone) && DateTime.now().difference(_peekAndPopController.pushTime).inSeconds > 1 ? InAppBrowser("https://flutter.dev") : peekAndPopController.stage == Stage.WillCancel || peekAndPopController.stage == Stage.IsCancelled ? Container() : const Center(child: const CupertinoActivityIndicator()),
235 | ),
236 | ),
237 | ),
238 | );
239 | }
240 |
241 | Widget specialPeekAndPopBuilder(BuildContext context, PeekAndPopControllerState _peekAndPopController) {
242 | if (_peekAndPopController.willBeDone || _peekAndPopController.isDone)
243 | return atPopWrapper(
244 | Transform.translate(
245 | offset: Offset(0, -50),
246 | child: Hero(
247 | tag: "Hero",
248 | child: Image.asset(
249 | "assets/Hero.png",
250 | fit: BoxFit.contain,
251 | key: Key("Image"),
252 | ),
253 | ),
254 | ),
255 | _peekAndPopController,
256 | );
257 | else
258 | return Image.asset(
259 | "assets/Hero.png",
260 | fit: BoxFit.contain,
261 | key: Key("Image"),
262 | );
263 | }
264 |
265 | Widget gridPeekAndPopBuilderAtPeek(int index, BuildContext context, PeekAndPopControllerState _peekAndPopController) {
266 | return atPeekWrapper(
267 | Image.asset(
268 | "assets/" + index.toString() + ".jpeg",
269 | fit: BoxFit.contain,
270 | key: Key("Image"),
271 | ),
272 | _peekAndPopController,
273 | );
274 | }
275 |
276 | Widget gridPeekAndPopBuilderAtPop(int index, BuildContext context, PeekAndPopControllerState _peekAndPopController) {
277 | return atPopWrapper(
278 | Transform.translate(
279 | offset: Offset(0, -50),
280 | child: Image.asset(
281 | "assets/" + index.toString() + ".jpeg",
282 | fit: BoxFit.contain,
283 | key: Key("Image"),
284 | ),
285 | ),
286 | _peekAndPopController,
287 | );
288 | }
289 |
290 | QuickActionsData moveableQuickActionsBuilder(PeekAndPopControllerState _peekAndPopController) {
291 | return QuickActionsData(
292 | const EdgeInsets.only(left: 12.5, top: 25, right: 12.5, bottom: 25),
293 | const BorderRadius.all(const Radius.circular(10.0)),
294 | [
295 | QuickAction(
296 | 60,
297 | () {
298 | _peekAndPopController.peekAndPopChild.quickActions.currentState.animationController.reverse();
299 | Future.wait([_peekAndPopController.peekAndPopChild.snapController.currentState.move(const Offset(0.0, 0.0))]).then((_) {
300 | _peekAndPopController.finishPeekAndPop(null);
301 | });
302 | },
303 | const BoxDecoration(
304 | color: CupertinoColors.white,
305 | border: const Border(
306 | bottom: const BorderSide(
307 | color: CupertinoColors.inactiveGray,
308 | width: 0.0,
309 | style: BorderStyle.solid,
310 | ),
311 | ),
312 | ),
313 | const Center(
314 | child: const Text(
315 | "Pop",
316 | style: const TextStyle(
317 | color: CupertinoColors.activeBlue,
318 | fontWeight: FontWeight.normal,
319 | fontSize: 20,
320 | ),
321 | textAlign: TextAlign.center,
322 | ),
323 | ),
324 | ),
325 | QuickAction(
326 | 60,
327 | () {},
328 | const BoxDecoration(
329 | color: CupertinoColors.white,
330 | border: const Border(
331 | bottom: const BorderSide(
332 | color: CupertinoColors.inactiveGray,
333 | width: 0.0,
334 | style: BorderStyle.solid,
335 | ),
336 | ),
337 | ),
338 | const Center(
339 | child: const Text(
340 | "Do Nothing",
341 | style: const TextStyle(
342 | color: CupertinoColors.activeBlue,
343 | fontWeight: FontWeight.normal,
344 | fontSize: 20,
345 | ),
346 | textAlign: TextAlign.center,
347 | ),
348 | ),
349 | ),
350 | QuickAction(
351 | 60,
352 | () {
353 | _peekAndPopController.peekAndPopChild.quickActions.currentState.animationController.reverse();
354 | Future.wait([_peekAndPopController.peekAndPopChild.snapController.currentState.move(const Offset(0.0, 0.0))]).then((_) {
355 | _peekAndPopController.cancelPeekAndPop(null);
356 | });
357 | },
358 | const BoxDecoration(
359 | color: CupertinoColors.white,
360 | border: const Border(
361 | top: const BorderSide(
362 | color: CupertinoColors.inactiveGray,
363 | width: 0.0,
364 | style: BorderStyle.solid,
365 | ),
366 | ),
367 | ),
368 | const Center(
369 | child: const Text(
370 | "Dismiss",
371 | style: const TextStyle(
372 | color: CupertinoColors.destructiveRed,
373 | fontWeight: FontWeight.normal,
374 | fontSize: 20,
375 | ),
376 | textAlign: TextAlign.center,
377 | ),
378 | ),
379 | ),
380 | ],
381 | );
382 | }
383 |
384 | QuickActionsData gridQuickActionsBuilder(PeekAndPopControllerState _peekAndPopController) {
385 | return QuickActionsData(
386 | const EdgeInsets.only(left: 12.5, top: 25, right: 12.5, bottom: 25),
387 | const BorderRadius.all(const Radius.circular(10.0)),
388 | [
389 | QuickAction(
390 | 60,
391 | () {
392 | _peekAndPopController.peekAndPopChild.quickActions.currentState.animationController.reverse();
393 | Future.wait([_peekAndPopController.peekAndPopChild.snapController.currentState.move(const Offset(0.0, 0.0))]).then((_) {
394 | _peekAndPopController.finishPeekAndPop(null);
395 | });
396 | },
397 | const BoxDecoration(
398 | color: CupertinoColors.white,
399 | border: const Border(
400 | bottom: const BorderSide(
401 | color: CupertinoColors.inactiveGray,
402 | width: 0.0,
403 | style: BorderStyle.solid,
404 | ),
405 | ),
406 | ),
407 | const Center(
408 | child: const Text(
409 | "Pop",
410 | style: const TextStyle(
411 | color: CupertinoColors.activeBlue,
412 | fontWeight: FontWeight.normal,
413 | fontSize: 20,
414 | ),
415 | textAlign: TextAlign.center,
416 | ),
417 | ),
418 | ),
419 | QuickAction(
420 | 60,
421 | () {},
422 | const BoxDecoration(
423 | color: CupertinoColors.white,
424 | border: const Border(
425 | bottom: const BorderSide(
426 | color: CupertinoColors.inactiveGray,
427 | width: 0.0,
428 | style: BorderStyle.solid,
429 | ),
430 | ),
431 | ),
432 | const Center(
433 | child: const Text(
434 | "Save",
435 | style: const TextStyle(
436 | color: CupertinoColors.activeBlue,
437 | fontWeight: FontWeight.normal,
438 | fontSize: 20,
439 | ),
440 | textAlign: TextAlign.center,
441 | ),
442 | ),
443 | ),
444 | QuickAction(
445 | 60,
446 | () {},
447 | const BoxDecoration(
448 | color: CupertinoColors.white,
449 | border: const Border(
450 | bottom: const BorderSide(
451 | color: CupertinoColors.inactiveGray,
452 | width: 0.0,
453 | style: BorderStyle.solid,
454 | ),
455 | ),
456 | ),
457 | const Center(
458 | child: const Text(
459 | "Share",
460 | style: const TextStyle(
461 | color: CupertinoColors.activeBlue,
462 | fontWeight: FontWeight.normal,
463 | fontSize: 20,
464 | ),
465 | textAlign: TextAlign.center,
466 | ),
467 | ),
468 | ),
469 | QuickAction(
470 | 60,
471 | () {
472 | _peekAndPopController.peekAndPopChild.quickActions.currentState.animationController.reverse();
473 | Future.wait([_peekAndPopController.peekAndPopChild.snapController.currentState.move(const Offset(0.0, 0.0))]).then((_) {
474 | _peekAndPopController.cancelPeekAndPop(null);
475 | });
476 | },
477 | const BoxDecoration(
478 | color: CupertinoColors.white,
479 | border: const Border(
480 | top: const BorderSide(
481 | color: CupertinoColors.inactiveGray,
482 | width: 0.0,
483 | style: BorderStyle.solid,
484 | ),
485 | ),
486 | ),
487 | const Center(
488 | child: const Text(
489 | "Dismiss",
490 | style: const TextStyle(
491 | color: CupertinoColors.destructiveRed,
492 | fontWeight: FontWeight.normal,
493 | fontSize: 20,
494 | ),
495 | textAlign: TextAlign.center,
496 | ),
497 | ),
498 | ),
499 | ],
500 | );
501 | }
502 |
503 | @override
504 | Widget build(BuildContext context) {
505 | return Scaffold(
506 | appBar: AppBar(title: Text(widget.title)),
507 | body: PeekAndPopMisc.scaleDownWrapper(
508 | PageView(
509 | children: [
510 | Column(
511 | mainAxisAlignment: MainAxisAlignment.center,
512 | children: [
513 | Expanded(
514 | child: paddingWrapper(
515 | PeekAndPopController(
516 | normalRow(
517 | "Normal with Overlap & without Alignment",
518 | Colors.redAccent,
519 | ),
520 | true,
521 | peekAndPopBuilderAtPeek: normalPeekAndPopBuilderAtPeek,
522 | peekAndPopBuilderAtPop: normalPeekAndPopBuilderAtPop,
523 | sigma: 10,
524 | backdropColor: Colors.white,
525 | useOverlap: true,
526 | useAlignment: false,
527 | indicatorScaleUpCoefficient: 0.01,
528 | onPushPeekAndPop: onPushPeekAndPop,
529 | peekScale: 0.95,
530 | peekCoefficient: 0.025,
531 | ),
532 | ),
533 | ),
534 | Expanded(
535 | child: paddingWrapper(
536 | PeekAndPopController(
537 | normalRow(
538 | "Moveable with Alignment & without Overlap",
539 | Colors.deepPurpleAccent,
540 | ),
541 | true,
542 | peekAndPopBuilderAtPeek: normalPeekAndPopBuilderAtPeek,
543 | peekAndPopBuilderAtPop: normalPeekAndPopBuilderAtPop,
544 | quickActionsBuilder: moveableQuickActionsBuilder,
545 | sigma: 10,
546 | backdropColor: Colors.white,
547 | useOverlap: false,
548 | useAlignment: true,
549 | indicatorScaleUpCoefficient: 0.01,
550 | onPushPeekAndPop: onPushPeekAndPop,
551 | peekScale: 0.95,
552 | peekCoefficient: 0.025,
553 | ),
554 | ),
555 | ),
556 | Expanded(
557 | child: paddingWrapper(
558 | PeekAndPopController(
559 | normalRow(
560 | "Platform View with Custom Overlap Rect",
561 | Colors.cyan,
562 | ),
563 | true,
564 | peekAndPopBuilder: platformViewPeekAndPopBuilder,
565 | peekAndPopBuilderUseCache: false,
566 | sigma: 10,
567 | backdropColor: Colors.white,
568 | useOverlap: true,
569 | customOverlapRect: Rect.fromLTRB(
570 | MediaQuery.of(context).size.width * 0.25,
571 | MediaQuery.of(context).size.height * 0.25,
572 | MediaQuery.of(context).size.width * 0.25,
573 | MediaQuery.of(context).size.height * 0.25,
574 | ),
575 | useAlignment: true,
576 | indicatorScaleUpCoefficient: 0.01,
577 | onPushPeekAndPop: onPushPeekAndPop,
578 | peekScale: 0.75,
579 | peekCoefficient: 0.025,
580 | ),
581 | ),
582 | ),
583 | Expanded(
584 | child: paddingWrapper(
585 | PeekAndPopController(
586 | specialRow(
587 | "Hero with Overlap & without Alignment",
588 | Colors.greenAccent,
589 | ),
590 | true,
591 | peekAndPopBuilder: specialPeekAndPopBuilder,
592 | peekAndPopBuilderUseCache: false,
593 | sigma: 10,
594 | backdropColor: Colors.white,
595 | useOverlap: true,
596 | useAlignment: false,
597 | indicatorScaleUpCoefficient: 0.01,
598 | onPushPeekAndPop: onPushPeekAndPop,
599 | peekScale: 0.95,
600 | peekCoefficient: 0.025,
601 | ),
602 | ),
603 | ),
604 | ],
605 | ),
606 | GridView.count(
607 | padding: EdgeInsets.all(25),
608 | mainAxisSpacing: 10.0,
609 | crossAxisSpacing: 10.0,
610 | crossAxisCount: 3,
611 | children: List.generate(30, (int index) {
612 | return PeekAndPopController(
613 | Container(
614 | decoration: BoxDecoration(
615 | image: DecorationImage(
616 | image: AssetImage(
617 | "assets/" + index.toString() + ".jpeg",
618 | ),
619 | fit: BoxFit.cover,
620 | ),
621 | borderRadius: const BorderRadius.all(const Radius.circular(10.0)),
622 | ),
623 | ),
624 | true,
625 | peekAndPopBuilderAtPeek: (BuildContext context, PeekAndPopControllerState _peekAndPopController) => gridPeekAndPopBuilderAtPeek(index, context, _peekAndPopController),
626 | peekAndPopBuilderAtPop: (BuildContext context, PeekAndPopControllerState _peekAndPopController) => gridPeekAndPopBuilderAtPop(index, context, _peekAndPopController),
627 | quickActionsBuilder: gridQuickActionsBuilder,
628 | sigma: 10,
629 | backdropColor: Colors.white,
630 | useOverlap: true,
631 | useAlignment: false,
632 | indicatorScaleUpCoefficient: 0.01,
633 | onPushPeekAndPop: onPushPeekAndPop,
634 | peekScale: 0.95,
635 | peekCoefficient: 0.025,
636 | );
637 | }),
638 | ),
639 | ],
640 | ),
641 | 0.04,
642 | ),
643 | );
644 | }
645 | }
646 |
647 | class InAppBrowser extends StatefulWidget {
648 | final String url;
649 |
650 | const InAppBrowser(
651 | this.url,
652 | );
653 |
654 | @override
655 | InAppBrowserState createState() {
656 | return InAppBrowserState(url);
657 | }
658 | }
659 |
660 | class InAppBrowserState extends State {
661 | final String url;
662 |
663 | InAppBrowserState(
664 | this.url,
665 | );
666 |
667 | @override
668 | Widget build(BuildContext context) {
669 | return WebView(
670 | initialUrl: url,
671 | javascriptMode: JavascriptMode.unrestricted,
672 | navigationDelegate: (NavigationRequest request) => NavigationDecision.navigate,
673 | onPageFinished: (String url) {},
674 | );
675 | }
676 | }
677 |
--------------------------------------------------------------------------------
/peek_and_pop/example/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "2.5.0-nullsafety"
11 | bloc:
12 | dependency: transitive
13 | description:
14 | name: bloc
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "6.0.3"
18 | boolean_selector:
19 | dependency: transitive
20 | description:
21 | name: boolean_selector
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "2.1.0-nullsafety"
25 | characters:
26 | dependency: transitive
27 | description:
28 | name: characters
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "1.1.0-nullsafety.2"
32 | charcode:
33 | dependency: transitive
34 | description:
35 | name: charcode
36 | url: "https://pub.dartlang.org"
37 | source: hosted
38 | version: "1.2.0-nullsafety"
39 | clock:
40 | dependency: transitive
41 | description:
42 | name: clock
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "1.1.0-nullsafety"
46 | collection:
47 | dependency: transitive
48 | description:
49 | name: collection
50 | url: "https://pub.dartlang.org"
51 | source: hosted
52 | version: "1.15.0-nullsafety.2"
53 | cupertino_icons:
54 | dependency: "direct main"
55 | description:
56 | name: cupertino_icons
57 | url: "https://pub.dartlang.org"
58 | source: hosted
59 | version: "0.1.2"
60 | fake_async:
61 | dependency: transitive
62 | description:
63 | name: fake_async
64 | url: "https://pub.dartlang.org"
65 | source: hosted
66 | version: "1.1.0-nullsafety"
67 | flick:
68 | dependency: transitive
69 | description:
70 | name: flick
71 | url: "https://pub.dartlang.org"
72 | source: hosted
73 | version: "1.0.3"
74 | flutter:
75 | dependency: "direct main"
76 | description: flutter
77 | source: sdk
78 | version: "0.0.0"
79 | flutter_test:
80 | dependency: "direct dev"
81 | description: flutter
82 | source: sdk
83 | version: "0.0.0"
84 | matcher:
85 | dependency: transitive
86 | description:
87 | name: matcher
88 | url: "https://pub.dartlang.org"
89 | source: hosted
90 | version: "0.12.10-nullsafety"
91 | meta:
92 | dependency: transitive
93 | description:
94 | name: meta
95 | url: "https://pub.dartlang.org"
96 | source: hosted
97 | version: "1.3.0-nullsafety.2"
98 | path:
99 | dependency: transitive
100 | description:
101 | name: path
102 | url: "https://pub.dartlang.org"
103 | source: hosted
104 | version: "1.8.0-nullsafety"
105 | peek_and_pop:
106 | dependency: "direct main"
107 | description:
108 | path: ".."
109 | relative: true
110 | source: path
111 | version: "1.0.3"
112 | sky_engine:
113 | dependency: transitive
114 | description: flutter
115 | source: sdk
116 | version: "0.0.99"
117 | snap:
118 | dependency: transitive
119 | description:
120 | name: snap
121 | url: "https://pub.dartlang.org"
122 | source: hosted
123 | version: "1.0.5"
124 | source_span:
125 | dependency: transitive
126 | description:
127 | name: source_span
128 | url: "https://pub.dartlang.org"
129 | source: hosted
130 | version: "1.8.0-nullsafety"
131 | stack_trace:
132 | dependency: transitive
133 | description:
134 | name: stack_trace
135 | url: "https://pub.dartlang.org"
136 | source: hosted
137 | version: "1.10.0-nullsafety"
138 | stream_channel:
139 | dependency: transitive
140 | description:
141 | name: stream_channel
142 | url: "https://pub.dartlang.org"
143 | source: hosted
144 | version: "2.1.0-nullsafety"
145 | string_scanner:
146 | dependency: transitive
147 | description:
148 | name: string_scanner
149 | url: "https://pub.dartlang.org"
150 | source: hosted
151 | version: "1.1.0-nullsafety"
152 | term_glyph:
153 | dependency: transitive
154 | description:
155 | name: term_glyph
156 | url: "https://pub.dartlang.org"
157 | source: hosted
158 | version: "1.2.0-nullsafety"
159 | test_api:
160 | dependency: transitive
161 | description:
162 | name: test_api
163 | url: "https://pub.dartlang.org"
164 | source: hosted
165 | version: "0.2.19-nullsafety"
166 | transparent_image:
167 | dependency: transitive
168 | description:
169 | name: transparent_image
170 | url: "https://pub.dartlang.org"
171 | source: hosted
172 | version: "1.0.0"
173 | typed_data:
174 | dependency: transitive
175 | description:
176 | name: typed_data
177 | url: "https://pub.dartlang.org"
178 | source: hosted
179 | version: "1.3.0-nullsafety.2"
180 | vector_math:
181 | dependency: transitive
182 | description:
183 | name: vector_math
184 | url: "https://pub.dartlang.org"
185 | source: hosted
186 | version: "2.1.0-nullsafety.2"
187 | webview_flutter:
188 | dependency: "direct main"
189 | description:
190 | name: webview_flutter
191 | url: "https://pub.dartlang.org"
192 | source: hosted
193 | version: "0.3.13"
194 | sdks:
195 | dart: ">=2.10.0-0.0.dev <2.10.0"
196 | flutter: ">=1.5.0 <2.0.0"
197 |
--------------------------------------------------------------------------------
/peek_and_pop/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name : example
2 | description : Example Project for peek_and_pop.
3 | version : 1.0.3
4 | author : Ali Yigit Bireroglu
5 | repository : https://github.com/aliyigitbireroglu/flutter-peek-and-pop
6 | homepage : https://www.cosmossoftware.coffee
7 |
8 | environment :
9 | sdk: ">=2.1.0 <3.0.0"
10 |
11 | dependencies :
12 | flutter :
13 | sdk: flutter
14 | peek_and_pop :
15 | path: ../
16 | cupertino_icons: ^0.1.2
17 | webview_flutter: ^0.3.13
18 |
19 | dev_dependencies:
20 | flutter_test:
21 | sdk: flutter
22 |
23 | flutter :
24 | uses-material-design: true
25 |
26 | assets :
27 | - assets/
28 |
--------------------------------------------------------------------------------
/peek_and_pop/example/test/example_test.dart:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/example/test/example_test.dart
--------------------------------------------------------------------------------
/peek_and_pop/lib/Export.dart:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 | // © Cosmos Software | Ali Yigit Bireroglu /
3 | // All material used in the making of this code, project, program, application, software et cetera (the "Intellectual Property") /
4 | // belongs completely and solely to Ali Yigit Bireroglu. This includes but is not limited to the source code, the multimedia and /
5 | // other asset files. If you were granted this Intellectual Property for personal use, you are obligated to include this copyright /
6 | // text at all times. /
7 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8 | //@formatter:off
9 |
10 | export 'peek_and_pop_controller.dart';
11 | export 'peek_and_pop_detector.dart';
12 | export 'peek_and_pop_child.dart';
13 | export 'misc.dart';
14 |
--------------------------------------------------------------------------------
/peek_and_pop/lib/animated_cross_fade.dart:
--------------------------------------------------------------------------------
1 | // Copyright 2016 The Chromium Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | import 'package:flutter/rendering.dart';
6 |
7 | import 'package:flutter/widgets.dart';
8 |
9 | // Examples can assume:
10 | // bool _first;
11 |
12 | /// Specifies which of two children to show. See [AnimatedCrossFade].
13 | ///
14 | /// The child that is shown will fade in, while the other will fade out.
15 | enum CrossFadeState {
16 | /// Show the first child ([AnimatedCrossFade.firstChild]) and hide the second
17 | /// ([AnimatedCrossFade.secondChild]]).
18 | showFirst,
19 |
20 | /// Show the second child ([AnimatedCrossFade.secondChild]) and hide the first
21 | /// ([AnimatedCrossFade.firstChild]).
22 | showSecond,
23 | }
24 |
25 | /// Signature for the [AnimatedCrossFade.layoutBuilder] callback.
26 | ///
27 | /// The `topChild` is the child fading in, which is normally drawn on top. The
28 | /// `bottomChild` is the child fading out, normally drawn on the bottom.
29 | ///
30 | /// For good performance, the returned widget tree should contain both the
31 | /// `topChild` and the `bottomChild`; the depth of the tree, and the types of
32 | /// the widgets in the tree, from the returned widget to each of the children
33 | /// should be the same; and where there is a widget with multiple children, the
34 | /// top child and the bottom child should be keyed using the provided
35 | /// `topChildKey` and `bottomChildKey` keys respectively.
36 | ///
37 | /// {@tool sample}
38 | ///
39 | /// ```dart
40 | /// Widget defaultLayoutBuilder(Widget topChild, Key topChildKey, Widget bottomChild, Key bottomChildKey) {
41 | /// return Stack(
42 | /// fit: StackFit.loose,
43 | /// children: [
44 | /// Positioned(
45 | /// key: bottomChildKey,
46 | /// left: 0.0,
47 | /// top: 0.0,
48 | /// right: 0.0,
49 | /// child: bottomChild,
50 | /// ),
51 | /// Positioned(
52 | /// key: topChildKey,
53 | /// child: topChild,
54 | /// )
55 | /// ],
56 | /// );
57 | /// }
58 | /// ```
59 | /// {@end-tool}
60 | typedef AnimatedCrossFadeBuilder = Widget Function(Widget topChild, Key topChildKey, Widget bottomChild, Key bottomChildKey);
61 |
62 | /// A widget that cross-fades between two given children and animates itself
63 | /// between their sizes.
64 | ///
65 | /// The animation is controlled through the [crossFadeState] parameter.
66 | /// [firstCurve] and [secondCurve] represent the opacity curves of the two
67 | /// children. The [firstCurve] is inverted, i.e. it fades out when providing a
68 | /// growing curve like [Curves.linear]. The [sizeCurve] is the curve used to
69 | /// animate between the size of the fading-out child and the size of the
70 | /// fading-in child.
71 | ///
72 | /// This widget is intended to be used to fade a pair of widgets with the same
73 | /// width. In the case where the two children have different heights, the
74 | /// animation crops overflowing children during the animation by aligning their
75 | /// top edge, which means that the bottom will be clipped.
76 | ///
77 | /// The animation is automatically triggered when an existing
78 | /// [AnimatedCrossFade] is rebuilt with a different value for the
79 | /// [crossFadeState] property.
80 | ///
81 | /// {@tool sample}
82 | ///
83 | /// This code fades between two representations of the Flutter logo. It depends
84 | /// on a boolean field `_first`; when `_first` is true, the first logo is shown,
85 | /// otherwise the second logo is shown. When the field changes state, the
86 | /// [AnimatedCrossFade] widget cross-fades between the two forms of the logo
87 | /// over three seconds.
88 | ///
89 | /// ```dart
90 | /// AnimatedCrossFade(
91 | /// duration: const Duration(seconds: 3),
92 | /// firstChild: const FlutterLogo(style: FlutterLogoStyle.horizontal, size: 100.0),
93 | /// secondChild: const FlutterLogo(style: FlutterLogoStyle.stacked, size: 100.0),
94 | /// crossFadeState: _first ? CrossFadeState.showFirst : CrossFadeState.showSecond,
95 | /// )
96 | /// ```
97 | /// {@end-tool}
98 | ///
99 | /// See also:
100 | ///
101 | /// * [AnimatedSize], the lower-level widget which [AnimatedCrossFade] uses to
102 | /// automatically change size.
103 | /// * [AnimatedSwitcher], which switches out a child for a new one with a
104 | /// customizable transition.
105 | class AnimatedCrossFade extends StatefulWidget {
106 | /// Creates a cross-fade animation widget.
107 | ///
108 | /// The [duration] of the animation is the same for all components (fade in,
109 | /// fade out, and size), and you can pass [Interval]s instead of [Curve]s in
110 | /// order to have finer control, e.g., creating an overlap between the fades.
111 | ///
112 | /// All the arguments other than [key] must be non-null.
113 | const AnimatedCrossFade({
114 | Key key,
115 | @required this.firstChild,
116 | @required this.secondChild,
117 | this.firstCurve = Curves.linear,
118 | this.secondCurve = Curves.linear,
119 | this.sizeCurve = Curves.linear,
120 | this.alignment = Alignment.topCenter,
121 | @required this.crossFadeState,
122 | @required this.duration,
123 | this.reverseDuration,
124 | this.layoutBuilder = defaultLayoutBuilder,
125 | }) : assert(firstChild != null),
126 | assert(secondChild != null),
127 | assert(firstCurve != null),
128 | assert(secondCurve != null),
129 | assert(sizeCurve != null),
130 | assert(alignment != null),
131 | assert(crossFadeState != null),
132 | assert(duration != null),
133 | assert(layoutBuilder != null),
134 | super(key: key);
135 |
136 | /// The child that is visible when [crossFadeState] is
137 | /// [CrossFadeState.showFirst]. It fades out when transitioning
138 | /// [crossFadeState] from [CrossFadeState.showFirst] to
139 | /// [CrossFadeState.showSecond] and vice versa.
140 | final Widget firstChild;
141 |
142 | /// The child that is visible when [crossFadeState] is
143 | /// [CrossFadeState.showSecond]. It fades in when transitioning
144 | /// [crossFadeState] from [CrossFadeState.showFirst] to
145 | /// [CrossFadeState.showSecond] and vice versa.
146 | final Widget secondChild;
147 |
148 | /// The child that will be shown when the animation has completed.
149 | final CrossFadeState crossFadeState;
150 |
151 | /// The duration of the whole orchestrated animation.
152 | final Duration duration;
153 |
154 | /// The duration of the whole orchestrated animation when running in reverse.
155 | ///
156 | /// If not supplied, this defaults to [duration].
157 | final Duration reverseDuration;
158 |
159 | /// The fade curve of the first child.
160 | ///
161 | /// Defaults to [Curves.linear].
162 | final Curve firstCurve;
163 |
164 | /// The fade curve of the second child.
165 | ///
166 | /// Defaults to [Curves.linear].
167 | final Curve secondCurve;
168 |
169 | /// The curve of the animation between the two children's sizes.
170 | ///
171 | /// Defaults to [Curves.linear].
172 | final Curve sizeCurve;
173 |
174 | /// How the children should be aligned while the size is animating.
175 | ///
176 | /// Defaults to [Alignment.topCenter].
177 | ///
178 | /// See also:
179 | ///
180 | /// * [Alignment], a class with convenient constants typically used to
181 | /// specify an [AlignmentGeometry].
182 | /// * [AlignmentDirectional], like [Alignment] for specifying alignments
183 | /// relative to text direction.
184 | final AlignmentGeometry alignment;
185 |
186 | /// A builder that positions the [firstChild] and [secondChild] widgets.
187 | ///
188 | /// The widget returned by this method is wrapped in an [AnimatedSize].
189 | ///
190 | /// By default, this uses [AnimatedCrossFade.defaultLayoutBuilder], which uses
191 | /// a [Stack] and aligns the `bottomChild` to the top of the stack while
192 | /// providing the `topChild` as the non-positioned child to fill the provided
193 | /// constraints. This works well when the [AnimatedCrossFade] is in a position
194 | /// to change size and when the children are not flexible. However, if the
195 | /// children are less fussy about their sizes (for example a
196 | /// [CircularProgressIndicator] inside a [Center]), or if the
197 | /// [AnimatedCrossFade] is being forced to a particular size, then it can
198 | /// result in the widgets jumping about when the cross-fade state is changed.
199 | final AnimatedCrossFadeBuilder layoutBuilder;
200 |
201 | /// The default layout algorithm used by [AnimatedCrossFade].
202 | ///
203 | /// The top child is placed in a stack that sizes itself to match the top
204 | /// child. The bottom child is positioned at the top of the same stack, sized
205 | /// to fit its width but without forcing the height. The stack is then
206 | /// clipped.
207 | ///
208 | /// This is the default value for [layoutBuilder]. It implements
209 | /// [AnimatedCrossFadeBuilder].
210 | static Widget defaultLayoutBuilder(Widget topChild, Key topChildKey, Widget bottomChild, Key bottomChildKey) {
211 | return Stack(
212 | overflow: Overflow.visible,
213 | children: [
214 | Positioned(
215 | key: bottomChildKey,
216 | left: 0.0,
217 | top: 0.0,
218 | right: 0.0,
219 | child: bottomChild,
220 | ),
221 | Positioned(
222 | key: topChildKey,
223 | child: topChild,
224 | ),
225 | ],
226 | );
227 | }
228 |
229 | @override
230 | _AnimatedCrossFadeState createState() => _AnimatedCrossFadeState();
231 |
232 | @override
233 | void debugFillProperties(DiagnosticPropertiesBuilder properties) {
234 | super.debugFillProperties(properties);
235 | properties.add(EnumProperty('crossFadeState', crossFadeState));
236 | properties.add(DiagnosticsProperty('alignment', alignment, defaultValue: Alignment.topCenter));
237 | properties.add(IntProperty('duration', duration.inMilliseconds, unit: 'ms'));
238 | properties.add(IntProperty('reverseDuration', reverseDuration?.inMilliseconds, unit: 'ms', defaultValue: null));
239 | }
240 | }
241 |
242 | class _AnimatedCrossFadeState extends State with TickerProviderStateMixin {
243 | AnimationController _controller;
244 | Animation _firstAnimation;
245 | Animation _secondAnimation;
246 |
247 | @override
248 | void initState() {
249 | super.initState();
250 | _controller = AnimationController(
251 | duration: widget.duration,
252 | reverseDuration: widget.reverseDuration,
253 | vsync: this,
254 | );
255 | if (widget.crossFadeState == CrossFadeState.showSecond) _controller.value = 1.0;
256 | _firstAnimation = _initAnimation(widget.firstCurve, true);
257 | _secondAnimation = _initAnimation(widget.secondCurve, false);
258 | _controller.addStatusListener((AnimationStatus status) {
259 | setState(() {
260 | // Trigger a rebuild because it depends on _isTransitioning, which
261 | // changes its value together with animation status.
262 | });
263 | });
264 | }
265 |
266 | Animation _initAnimation(Curve curve, bool inverted) {
267 | Animation result = _controller.drive(CurveTween(curve: curve));
268 | if (inverted) result = result.drive(Tween(begin: 1.0, end: 0.0));
269 | return result;
270 | }
271 |
272 | @override
273 | void dispose() {
274 | _controller.dispose();
275 | super.dispose();
276 | }
277 |
278 | @override
279 | void didUpdateWidget(AnimatedCrossFade oldWidget) {
280 | super.didUpdateWidget(oldWidget);
281 | if (widget.duration != oldWidget.duration) _controller.duration = widget.duration;
282 | if (widget.reverseDuration != oldWidget.reverseDuration) _controller.reverseDuration = widget.reverseDuration;
283 | if (widget.firstCurve != oldWidget.firstCurve) _firstAnimation = _initAnimation(widget.firstCurve, true);
284 | if (widget.secondCurve != oldWidget.secondCurve) _secondAnimation = _initAnimation(widget.secondCurve, false);
285 | if (widget.crossFadeState != oldWidget.crossFadeState) {
286 | switch (widget.crossFadeState) {
287 | case CrossFadeState.showFirst:
288 | _controller.reverse();
289 | break;
290 | case CrossFadeState.showSecond:
291 | _controller.forward();
292 | break;
293 | }
294 | }
295 | }
296 |
297 | /// Whether we're in the middle of cross-fading this frame.
298 | bool get _isTransitioning => _controller.status == AnimationStatus.forward || _controller.status == AnimationStatus.reverse;
299 |
300 | @override
301 | Widget build(BuildContext context) {
302 | const Key kFirstChildKey = ValueKey(CrossFadeState.showFirst);
303 | const Key kSecondChildKey = ValueKey(CrossFadeState.showSecond);
304 | final bool transitioningForwards = _controller.status == AnimationStatus.completed || _controller.status == AnimationStatus.forward;
305 | Key topKey;
306 | Widget topChild;
307 | Animation topAnimation;
308 | Key bottomKey;
309 | Widget bottomChild;
310 | Animation bottomAnimation;
311 | if (transitioningForwards) {
312 | topKey = kSecondChildKey;
313 | topChild = widget.secondChild;
314 | topAnimation = _secondAnimation;
315 | bottomKey = kFirstChildKey;
316 | bottomChild = widget.firstChild;
317 | bottomAnimation = _firstAnimation;
318 | } else {
319 | topKey = kFirstChildKey;
320 | topChild = widget.firstChild;
321 | topAnimation = _firstAnimation;
322 | bottomKey = kSecondChildKey;
323 | bottomChild = widget.secondChild;
324 | bottomAnimation = _secondAnimation;
325 | }
326 |
327 | bottomChild = TickerMode(
328 | key: bottomKey,
329 | enabled: _isTransitioning,
330 | child: ExcludeSemantics(
331 | excluding: true, // Always exclude the semantics of the widget that's fading out.
332 | child: FadeTransition(
333 | opacity: bottomAnimation,
334 | child: bottomChild,
335 | ),
336 | ),
337 | );
338 | topChild = TickerMode(
339 | key: topKey, enabled: true, // Top widget always has its animations enabled.
340 | child: ExcludeSemantics(
341 | excluding: false, // Always publish semantics for the widget that's fading in.
342 | child: FadeTransition(
343 | opacity: topAnimation,
344 | child: topChild,
345 | ),
346 | ),
347 | );
348 | return AnimatedSize(
349 | alignment: widget.alignment,
350 | duration: widget.duration,
351 | reverseDuration: widget.reverseDuration,
352 | curve: widget.sizeCurve,
353 | vsync: this,
354 | child: widget.layoutBuilder(topChild, topKey, bottomChild, bottomKey),
355 | );
356 | }
357 |
358 | @override
359 | void debugFillProperties(DiagnosticPropertiesBuilder description) {
360 | super.debugFillProperties(description);
361 | description.add(EnumProperty('crossFadeState', widget.crossFadeState));
362 | description.add(DiagnosticsProperty('controller', _controller, showName: false));
363 | description.add(DiagnosticsProperty('alignment', widget.alignment, defaultValue: Alignment.topCenter));
364 | }
365 | }
366 |
--------------------------------------------------------------------------------
/peek_and_pop/lib/misc.dart:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 | // © Cosmos Software | Ali Yigit Bireroglu /
3 | // All material used in the making of this code, project, program, application, software et cetera (the "Intellectual Property") /
4 | // belongs completely and solely to Ali Yigit Bireroglu. This includes but is not limited to the source code, the multimedia and /
5 | // other asset files. If you were granted this Intellectual Property for personal use, you are obligated to include this copyright /
6 | // text at all times. /
7 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8 | //@formatter:off
9 |
10 | import 'package:flutter/widgets.dart';
11 |
12 | import 'package:bloc/bloc.dart';
13 |
14 | import 'Export.dart';
15 |
16 | typedef PeekAndPopBuilder = Widget Function(BuildContext context, PeekAndPopControllerState _peekAndPopController);
17 | typedef PeekAndPopProcessNotifier = bool Function(PeekAndPopControllerState _peekAndPopController);
18 | typedef PeekAndPopProcessCallback = void Function(PeekAndPopControllerState _peekAndPopController);
19 | typedef PeekAndPopGestureCallback = void Function(dynamic pressDetails);
20 | typedef QuickActionsBuilder = QuickActionsData Function(PeekAndPopControllerState _peekAndPopController);
21 |
22 | ///See [PeekAndPopControllerState.stage].
23 | enum Stage {
24 | None,
25 | WillPush,
26 | IsPushed,
27 | WillPeek,
28 | IsPeeking,
29 | WillCancel,
30 | IsCancelled,
31 | WillFinish,
32 | IsFinished,
33 | WillComplete,
34 | IsComplete,
35 | WillClose,
36 | IsClosed,
37 | }
38 |
39 | ///The new optimised blur effect algorithm during the Peek & Pop process requires your root CupertinoApp/MaterialApp to be wrapped in a
40 | ///[RepaintBoundary] widget which uses this key. See README, [PeekAndPopChildState.blurSnapshot] or [PeekAndPopChildState.blurTrackerNotifier] for more
41 | ///info.
42 | final GlobalKey background = GlobalKey();
43 |
44 | ///See [TransformBloc], [scaleUpWrapper] and [scaleDownWrapper].
45 | TransformBloc transformBloc = TransformBloc();
46 |
47 | ///Use this function to scale down a widget as the Peek & Pop process proceeds.
48 | Widget scaleDownWrapper(Widget child, double scaleDownCoefficient) {
49 | return StreamBuilder(
50 | stream: transformBloc,
51 | builder: (BuildContext context, AsyncSnapshot snapshot) {
52 | return Transform.scale(
53 | scale: snapshot.hasData ? (1.0 - (snapshot.data * scaleDownCoefficient)) : 1.0,
54 | child: child,
55 | );
56 | },
57 | );
58 | }
59 |
60 | ///Use this function to scale up a widget as the Peek & Pop process proceeds.
61 | Widget scaleUpWrapper(Widget child, double scaleUpCoefficient) {
62 | return StreamBuilder(
63 | stream: transformBloc,
64 | builder: (BuildContext context, AsyncSnapshot snapshot) {
65 | return Transform.scale(
66 | scale: snapshot.hasData ? (1.0 + (snapshot.data * scaleUpCoefficient)) : 1.0,
67 | child: child,
68 | );
69 | },
70 | );
71 | }
72 |
73 | ///A Bloc class for controlling the [scaleDownWrapper] and [scaleUpWrapper].
74 | class TransformBloc extends Bloc {
75 |
76 | TransformBloc(): super(0.0);
77 |
78 | @override
79 | Stream mapEventToState(double newState) async* {
80 | yield newState;
81 | }
82 | }
83 |
84 | ///A simple class for organising general Quick Actions information.
85 | class QuickActionsData {
86 | final EdgeInsets padding;
87 | final BorderRadius borderRadius;
88 | final List quickActions;
89 |
90 | const QuickActionsData(
91 | this.padding,
92 | this.borderRadius,
93 | this.quickActions,
94 | );
95 | }
96 |
97 | ///A simple class for organising an individual Quick Action information.
98 | class QuickAction {
99 | final double height;
100 | final Function onTap;
101 | final BoxDecoration boxDecoration;
102 | final Widget child;
103 |
104 | const QuickAction(
105 | this.height,
106 | this.onTap,
107 | this.boxDecoration,
108 | this.child,
109 | );
110 | }
111 |
112 | class PeekAndPopRoute extends PageRoute {
113 | final PeekAndPopControllerState _peekAndPopController;
114 |
115 | final WidgetBuilder builder;
116 |
117 | final Function pageTransition;
118 |
119 | PeekAndPopRoute(
120 | this._peekAndPopController,
121 | this.builder,
122 | this.pageTransition,
123 | );
124 |
125 | @override
126 | bool get opaque => false;
127 |
128 | @override
129 | bool get barrierDismissible => true;
130 |
131 | @override
132 | Color get barrierColor => Color.fromARGB(1, 0, 0, 0);
133 |
134 | @override
135 | String get barrierLabel => "";
136 |
137 | @override
138 | bool get maintainState => true;
139 |
140 | @override
141 | Duration get transitionDuration => const Duration(milliseconds: 333);
142 |
143 | @override
144 | Widget buildTransitions(BuildContext context, Animation animation, Animation secondaryAnimation, Widget child) {
145 | if (!_peekAndPopController.isDirect && !_peekAndPopController.ignoreAnimation && _peekAndPopController.stage != Stage.IsComplete) return child;
146 | if (pageTransition == null)
147 | return SlideTransition(
148 | position: Tween(
149 | begin: const Offset(0.0, 1.0),
150 | end: Offset.zero,
151 | ).animate(animation),
152 | child: child,
153 | );
154 | return pageTransition(
155 | context,
156 | animation,
157 | secondaryAnimation,
158 | child,
159 | );
160 | }
161 |
162 | @override
163 | Widget buildPage(BuildContext context, Animation animation, Animation secondaryAnimation) {
164 | return builder(context);
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/peek_and_pop/lib/peek_and_pop.dart:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 | // © Cosmos Software | Ali Yigit Bireroglu /
3 | // All material used in the making of this code, project, program, application, software et cetera (the "Intellectual Property") /
4 | // belongs completely and solely to Ali Yigit Bireroglu. This includes but is not limited to the source code, the multimedia and /
5 | // other asset files. If you were granted this Intellectual Property for personal use, you are obligated to include this copyright /
6 | // text at all times. /
7 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8 | //@formatter:off
9 |
10 | export 'Export.dart';
11 |
--------------------------------------------------------------------------------
/peek_and_pop/lib/peek_and_pop_detector.dart:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 | // © Cosmos Software | Ali Yigit Bireroglu /
3 | // All material used in the making of this code, project, program, application, software et cetera (the "Intellectual Property") /
4 | // belongs completely and solely to Ali Yigit Bireroglu. This includes but is not limited to the source code, the multimedia and /
5 | // other asset files. If you were granted this Intellectual Property for personal use, you are obligated to include this copyright /
6 | // text at all times. /
7 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8 | //@formatter:off
9 |
10 | import 'package:flutter/material.dart';
11 | import 'package:flutter/services.dart';
12 |
13 | import 'gesture_detector.dart' as MyGestureDetector;
14 | import 'Export.dart';
15 |
16 | ///The widget that is responsible of detecting Peek & Pop related gestures until the gesture recognition is rerouted to the instantiated
17 | ///[PeekAndPopChild]. It is automatically created by the [PeekAndPopController]. It uses [MyGestureDetector.GestureDetector] for reasons
18 | ///explained at [PeekAndPopController.startPressure] and [PeekAndPopController.peakPressure]
19 | class PeekAndPopDetector extends StatelessWidget {
20 | final PeekAndPopControllerState _peekAndPopController;
21 |
22 | final Widget child;
23 |
24 | const PeekAndPopDetector(
25 | this._peekAndPopController,
26 | this.child,
27 | );
28 |
29 | @override
30 | Widget build(BuildContext context) {
31 | return ValueListenableBuilder(
32 | child: _peekAndPopController.uiChildUseCache ? child : null,
33 | builder: (BuildContext context, int pressRerouted, Widget cachedChild) {
34 | return IgnorePointer(
35 | ignoring: pressRerouted != 0,
36 | child: MyGestureDetector.GestureDetector(
37 | startPressure: _peekAndPopController.startPressure,
38 | peakPressure: _peekAndPopController.peakPressure,
39 | onTap: () {
40 | HapticFeedback.mediumImpact();
41 | _peekAndPopController.peekAndPopComplete();
42 | },
43 | onForcePressStart: (ForcePressDetails forcePressDetails) {
44 | _peekAndPopController.pushPeekAndPop(forcePressDetails);
45 | },
46 | onForcePressUpdate: (ForcePressDetails forcePressDetails) {
47 | _peekAndPopController.updatePeekAndPop(forcePressDetails);
48 | },
49 | onForcePressEnd: (ForcePressDetails forcePressDetails) {
50 | _peekAndPopController.cancelPeekAndPop(forcePressDetails);
51 | },
52 | onForcePressPeak: (ForcePressDetails forcePressDetails) {
53 | _peekAndPopController.finishPeekAndPop(forcePressDetails);
54 | },
55 | child: _peekAndPopController.uiChildUseCache ? cachedChild : child,
56 | ),
57 | );
58 | },
59 | valueListenable: _peekAndPopController.pressReroutedNotifier,
60 | );
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/.flutter-plugins-dependencies:
--------------------------------------------------------------------------------
1 | {"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"webview_flutter","path":"/Users/fabriziotognetto/Library/flutter/.pub-cache/hosted/pub.dartlang.org/webview_flutter-0.3.13/","dependencies":[]}],"android":[{"name":"webview_flutter","path":"/Users/fabriziotognetto/Library/flutter/.pub-cache/hosted/pub.dartlang.org/webview_flutter-0.3.13/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"webview_flutter","dependencies":[]}],"date_created":"2020-09-23 23:07:44.981689","version":"1.22.0-12.1.pre"}
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/.gitignore:
--------------------------------------------------------------------------------
1 | /gitignore
2 | /android
3 | /build
4 | /ios
5 | .notes.md
6 | .notes.txt
7 |
8 | # Miscellaneous
9 | *.class
10 | *.log
11 | *.pyc
12 | *.swp
13 | .DS_Store
14 | .atom/
15 | .buildlog/
16 | .history
17 | .svn/
18 |
19 | # IntelliJ related
20 | *.iml
21 | *.ipr
22 | *.iws
23 | .idea/
24 |
25 | # The .vscode folder contains launch configuration and tasks you configure in
26 | # VS Code which you may wish to be included in version control, so this line
27 | # is commented out by default.
28 | #.vscode/
29 |
30 | # Flutter/Dart/Pub related
31 | **/doc/api/
32 | .dart_tool/
33 | .flutter-plugins
34 | .packages
35 | .pub-cache/
36 | .pub/
37 | build/
38 |
39 | # Android related
40 | **/android/**/gradle-wrapper.jar
41 | **/android/.gradle
42 | **/android/captures/
43 | **/android/gradlew
44 | **/android/gradlew.bat
45 | **/android/local.properties
46 | **/android/**/GeneratedPluginRegistrant.java
47 |
48 | # iOS/XCode related
49 | **/ios/**/*.mode1v3
50 | **/ios/**/*.mode2v3
51 | **/ios/**/*.moved-aside
52 | **/ios/**/*.pbxuser
53 | **/ios/**/*.perspectivev3
54 | **/ios/**/*sync/
55 | **/ios/**/.sconsign.dblite
56 | **/ios/**/.tags*
57 | **/ios/**/.vagrant/
58 | **/ios/**/DerivedData/
59 | **/ios/**/Icon?
60 | **/ios/**/Pods/
61 | **/ios/**/.symlinks/
62 | **/ios/**/profile
63 | **/ios/**/xcuserdata
64 | **/ios/.generated/
65 | **/ios/Flutter/App.framework
66 | **/ios/Flutter/Flutter.framework
67 | **/ios/Flutter/Generated.xcconfig
68 | **/ios/Flutter/app.flx
69 | **/ios/Flutter/app.zip
70 | **/ios/Flutter/flutter_assets/
71 | **/ios/ServiceDefinitions.json
72 | **/ios/Runner/GeneratedPluginRegistrant.*
73 |
74 | # Exceptions to above rules.
75 | !**/ios/**/default.mode1v3
76 | !**/ios/**/default.mode2v3
77 | !**/ios/**/default.pbxuser
78 | !**/ios/**/default.perspectivev3
79 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
80 |
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 7e361d746130ac1c56193cfbae796aa5601762b6
8 | channel: master
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [1.0.3] - 21.11.2019
2 |
3 | * Minor changes.
4 |
5 | ## [1.0.2] - 07.09.2019
6 |
7 | * Two new PeekAndPopBuilders are added to [PeekAndPopController]. Use [PeekAndPopController.peekAndPopBuilderAtPeek] and
8 | [PeekAndPopController.peekAndPopBuilderAtPop] for both convenience and improved performance.
9 |
10 | * Improved performance.
11 |
12 | * [1.0.2+1] Support for latest dependencies.
13 |
14 | ## [1.0.1] - 03.09.2019
15 |
16 | * Minor changes.
17 |
18 | ## [1.0.0] - 30.08.2019
19 |
20 | * The "Quick Actions" feature is now added. It is highly customisable and you can show a dynamic menu with quick action buttons as the view is
21 | dragged and snapped very easily. The drag and snap limits will be automatically set according to the menu and the view.
22 | [snap](https://pub.dev/packages/snap) is now implemented directly to the package. See this [video](https://youtu.be/IQq_ty5mRYU) for examples.
23 |
24 | * The "Overlap" and "Alignment" features are now added. These two features create a much more fluent Peek & Pop process that is much more similar
25 | to the actual iOS version. See this [video](https://youtu.be/IQq_ty5mRYU) for examples.
26 |
27 | * The "Scale Up" and "Scale Down" features are now added. You can use these features to scale a widget down or up as the Peek & Pop process
28 | proceeds. "Scale Up" is also supported for the "Indicator" feature out of the box. See this [video](https://youtu.be/IQq_ty5mRYU) for examples.
29 |
30 | * "isHero" is now removed. It wasn't playing well with the package algorithm and it is considered to be unnecessary for the Peek & Pop process.
31 | However, this shouldn't be a problem due to the addition of the new "Overlap" and "Alignment" features. If you must use a Hero widget, only use it
32 | while "willBeDone" or "isDone" is true.
33 |
34 | * A workaround is implemented to avoid a Flutter Engine bug that was causing trouble with the optimised blur effect algorithm.
35 |
36 | * Improved enumeration for the stage of the Peek & Pop process.
37 |
38 | * Improved performance.
39 |
40 | * Fine tuning.
41 |
42 | * Improved code style.
43 |
44 | * Improved example project.
45 |
46 | * Updated README.
47 |
48 | * Old installation instructions are removed. If you wish (for some reason) to use a version older than v0.1.9, see the README of that version for
49 | the relevant installation instructions.
50 |
51 | ## [0.2.0] - 23.08.2019
52 |
53 | * Improved performance.
54 |
55 | * Minor changes.
56 |
57 | * Improved code style with trailing commas.
58 |
59 | * [0.2.0+1] Minor changes.
60 |
61 | ## [0.1.9] - 20.08.2019
62 |
63 | * Modifications to Flutter's normal "binding.dart" are no longer required!
64 |
65 | * The Long Press version is temporarily removed. It will be added back soon.
66 |
67 | * Code excerpt added to the README.
68 |
69 | * Updated README.
70 |
71 | * [0.1.9+1] Updated README.
72 |
73 | ## [0.1.8] - 18.08.2019
74 |
75 | * Example project adapted to the updated [snap](https://pub.dev/packages/snap).
76 |
77 | * Minor changes.
78 |
79 | * [0.1.8+1] Updated README.
80 |
81 | ## [0.1.7] - 14.08.2019
82 |
83 | * The "Indicator" feature added. See this [video](https://youtu.be/wOWCV7HJzwc) for examples.
84 |
85 | * Improved performance.
86 |
87 | * Fine tuning.
88 |
89 | ## [0.1.6] - 12.08.2019
90 |
91 | * Improved Long Press version (still under development).
92 |
93 | * Fine tuning.
94 |
95 | * Improved documentation.
96 |
97 | * Updated README.
98 |
99 | ## [0.1.5] - 11.08.2019
100 |
101 | * Improved performance.
102 |
103 | * Improved code style.
104 |
105 | ## [0.1.4] - 11.08.2019
106 |
107 | * A minor bug is fixed.
108 |
109 | ## [0.1.3] - 07.08.2019
110 |
111 | * A minor bug in the example project is fixed.
112 |
113 | * Updated README:
114 |
115 | **Note**: Don't forget to add io.flutter.embedded_views_previewYES to your Info.plist. See
116 | [webview_flutter](https://pub.flutter-io.cn/packages/webview_flutter) for more info.
117 |
118 | ## [0.1.2] - 07.08.2019
119 |
120 | * [snap](https://pub.dev/packages/snap) is now implemented directly to the example.
121 |
122 | * More callbacks added for better control.
123 |
124 | * Simple enumeration for the stage of the Peek & Pop process added.
125 |
126 | * Improved animations.
127 |
128 | * Improved documentation.
129 |
130 | ## [0.1.1] - 06.08.2019
131 |
132 | * Improved code style.
133 |
134 | ## [0.1.0] - 06.08.2019
135 |
136 | * Improved Long Press version (still under development).
137 |
138 | * Improved documentation.
139 |
140 | ## [0.0.1] - 05.08.2019
141 |
142 | * Initial release.
143 |
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Ali Yigit Bireroglu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/README.md:
--------------------------------------------------------------------------------
1 | # example
2 |
3 | Example Project for peek_and_pop.
4 |
5 | Note: Don't forget to add io.flutter.embedded_views_previewYES to your Info.plist. See
6 | [webview_flutter](https://pub.flutter-io.cn/packages/webview_flutter) for more info.
7 |
8 |
9 | # peek_and_pop
10 |
11 | [comment]: <> (Badges)
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | [](https://pub.dev/packages/peek_and_pop)
26 | [](https://github.com/aliyigitbireroglu/flutter-peek-and-pop/blob/master/LICENSE)
27 |
28 | [comment]: <> (Introduction)
29 |
30 |
31 | Peek & Pop implementation for Flutter based on the iOS functionality of the same name.
32 |
33 | **Finally, the v1.0.0 release! More fluent, more optimised and more beautiful than ever. Very customisable and very easy to use.**
34 |
35 | **It is highly recommended to read the documentation and run the example project on a real device to fully understand and inspect the full range of
36 | capabilities.**
37 |
38 | [comment]: <> (ToC)
39 | [Media](#media) | [Description](#description) | [Installation](#installation) | [How-to-Use](#howtouse)
40 |
41 | [comment]: <> (Notice)
42 | ## Notice
43 | * **v0.1.9 and higher no longer requires any modifications to Flutter's normal "binding.dart"! You can leave your Flutter source code alone and happy.**
44 |
45 | * **If you are updating from an earlier version, you can revert your "binding.dart" to its original format.**
46 | * * *
47 | [comment]: <> (Recent)
48 | ## Recent
49 | * **The "Quick Actions" feature is now added. It is highly customisable and you can show a dynamic menu with quick action buttons as the view is
50 | dragged and snapped very easily. The drag and snap limits will be automatically set according to the menu and the view.
51 | [snap](https://pub.dev/packages/snap) is now implemented directly to the package. See [Media](#media) for examples.**
52 |
53 | * **The "Overlap" and "Alignment" features are now added. These two features create a much more fluent Peek & Pop process that is much more similar
54 | to the actual iOS version. See [Media](#media) for examples.**
55 |
56 | * **The "Scale Up" and "Scale Down" features are now added. You can use these features to scale a widget down or up as the Peek & Pop process
57 | proceeds. "Scale Up" is also supported for the "Indicator" feature out of the box.See [Media](#media) for examples.**
58 |
59 | * **Improved enumeration for the stage of the Peek & Pop process.**
60 |
61 | * **The "Indicator" feature is now added. See [Media](#media) for examples.**
62 |
63 | * **Animations are now up to 4x faster with the new optimised blur effect algorithm during the Peek & Pop process.**
64 | * * *
65 | [comment]: <> (Warning)
66 | ## Warning
67 | * **"isHero" is now removed. It wasn't playing well with the package algorithm and it is considered to be unnecessary for the Peek & Pop process.
68 | However, this shouldn't be a problem due to the addition of the new "Overlap" and "Alignment" features. If you must use a Hero widget, only use it
69 | while "willBeDone" or "isDone" is true.**
70 |
71 | * **Old installation instructions are removed. If you wish (for some reason) to use a version older than v0.1.9, see the README of that version for
72 | the relevant installation instructions.**
73 | * * *
74 |
75 |
76 | [comment]: <> (Media)
77 |
78 | ## Media
79 |
80 | Watch on **Youtube**:
81 |
82 | [**v1.0.0 Showcase Demo**](https://youtu.be/IQq_ty5mRYU) | [**v1.0.0 Technical Preview**](https://youtu.be/hIjoWfP0krA)
83 |
84 | [v0.1.7](https://youtu.be/wOWCV7HJzwc)
85 |
86 | [v0.1.0 Mixed](https://youtu.be/G5QLwGtcb1I)
87 |
88 | [v0.0.1 Normal](https://youtu.be/PaEpU31z_7Q) | [v0.0.1 Moveable](https://youtu.be/3TjCFwHoOiE) | [v0.0.1 Platform View](https://youtu.be/489YB-QuJ3k) | [v0.0.1 Hero](https://youtu.be/36DAwnFKSKI)
89 |
90 |
91 |
92 |
93 |
94 |
95 | [comment]: <> (Description)
96 |
97 | ## Description
98 | As a fan of the iOS Peek & Pop functionality, I decided to implement it for Flutter as well.
99 |
100 | The package has been tested on iOS but not yet on Android as I don't have access to an Android device with Force Press capabilities. Help about
101 | this would be appreciated.
102 |
103 | ~~For devices that don't support Force Press, the package comes with an adaptation to Long Press *however* the Long Press version of this package is
104 | still under development and is not yet fully tested so consider it as a developers preview.~~
105 |
106 | (The Long Press version is temporarily removed. It will be added back soon.)
107 |
108 | ##
109 | The power move of this package is what I like to call "Gesture Recognition Rerouting". Normally, when a new widget with GestureDetector or similar
110 | is pushed over an initial widget used for detecting Force Press or when Navigator is used to pop a new page, the user has to restart the gesture
111 | for Flutter to resume updating it. This package fixes that problem as explained in the documentation:
112 |
113 | ```
114 | //This function is called by the instantiated [PeekAndPopChild] once it is ready to be included in the Peek & Pop process. Perhaps the most
115 | //essential functionality of this package also takes places in this function: The gesture recognition is rerouted from the [PeekAndPopDetector]
116 | //to the instantiated [PeekAndPopChild]. This is important for avoiding the necessity of having the user stop and restart their Force Press.
117 | //Instead, the [PeekAndPopController] does this automatically so that the existing Force Press can continue to update even when if
118 | //[PeekAndPopDetector] is blocked by the view which is often the case especially when using PlatformViews.
119 | ```
120 |
121 |
122 | [comment]: <> (Installation)
123 |
124 | ## Installation
125 | *It is easy. Don't worry.*
126 |
127 | **If you do not wish to use PlatformViews you can skip the installation instructions.**
128 |
129 | **Old installation instructions are removed. If you wish (for some reason) to use a version older than v0.1.9, see the README of that version for
130 | the relevant installation instructions.**
131 |
132 | For properly displaying PlatformViews, this package requires the latest Flutter [master](https://github.com/flutter/flutter)
133 | branch. *Maybe* it will work with some other version too but tests made with the [webview_flutter](https://pub.flutter-io.cn/packages/webview_flutter)
134 | seem to only properly display with the latest Flutter [master](https://github.com/flutter/flutter) branch which has improved the PlatformViews that
135 | allow better functionalities such as proper scaling and proper clipping.
136 |
137 | If you do not wish to use PlatformViews, you can skip this step.
138 |
139 | To use latest Flutter [master](https://github.com/flutter/flutter) branch, run the following command.
140 |
141 | **Note**: Don't forget to add io.flutter.embedded_views_previewYES to your Info.plist. See
142 | [webview_flutter](https://pub.flutter-io.cn/packages/webview_flutter) for more info.
143 |
144 | ```
145 | $ git clone -b master https://github.com/flutter/flutter.git
146 | $ flutter channel master
147 | $ flutter upgrade
148 | $ flutter doctor
149 | $ ./flutter/bin/flutter --version
150 | ```
151 |
152 |
153 | [comment]: <> (How-to-Use)
154 |
155 | ## How-to-Use
156 | *Also easy.*
157 |
158 | First of all, as explained in the documentation:
159 |
160 | ```
161 | //I noticed that a fullscreen blur effect via the [BackdropFilter] widget is not good to use while running the animations required for the Peek &
162 | //Pop process as it causes a noticeable drop in the framerate- especially for devices with high resolutions. During a mostly static view, the
163 | //drop is acceptable. However, once the animations start running, this drop causes a visual disturbance. To prevent this, a new optimised blur
164 | //effect algorithm is implemented. Now, the [BackdropFilter] widget is only used until the animations are about to start. At that moment, it is
165 | //replaced by a static image. Therefore, to capture this image, your root CupertinoApp/MaterialApp MUST be wrapped in a [RepaintBoundary] widget
166 | //which uses the [background] key. As a result, the Peek & Pop process is now up to 4x more fluent.
167 | ```
168 |
169 | TL;DR: Wrap your root CupertinoApp/MaterialApp in a RepaintBoundary widget and use the background GlobalKey from "misc.dart".
170 |
171 | This is required for the new optimised blur effect algorithm:
172 |
173 | ```
174 | import 'package:peek_and_pop/misc.dart' as PeekAndPopMisc;
175 |
176 | class MyApp extends StatelessWidget {
177 | @override
178 | Widget build(BuildContext context) {
179 | return RepaintBoundary(
180 | key: PeekAndPopMisc.background,
181 | child: MaterialApp(
182 | title: 'Peek & Pop Demo',
183 | home: MyHomePage(title: 'Peek & Pop Demo')
184 | )
185 | );
186 | }
187 | }
188 | ```
189 |
190 | If you wish to use the "ScaleUp" or the "Scale Down" features, wrap the widgets you wish to scale down or scale up during the Peek & Pop process with
191 | the scaleUpWrapper and scaleDownWrapper functions from "misc.dart":
192 |
193 | ```
194 | @override
195 | Widget build(BuildContext context) {
196 | return Scaffold(
197 | appBar: AppBar(title: Text(widget.title)),
198 | body: PeekAndPopMisc.scaleDownWrapper(
199 | ...,
200 | 0.04,
201 | ),
202 | );
203 | }
204 | ```
205 |
206 | Then, create a PeekAndPopController such as:
207 |
208 | ```
209 | PeekAndPopController(
210 | uiChild(), //Widget uiChild
211 | false, //bool uiChildUseCache
212 | {Key key,
213 | peekAndPopBuilder,
214 | peekAndPopBuilderUseCache,
215 | peekAndPopBuilderAtPeek : peekAndPopBuilderAtPeek,
216 | peekAndPopBuilderAtPop : peekAndPopBuilderAtPop,
217 | quickActionsBuilder : quickActionsBuilder,
218 | sigma : 10,
219 | backdropColor : Colors.black,
220 | alpha : 126,
221 | overlayBuilder : overlayBuilder,
222 | useOverlap : true,
223 | customOverlapRect,
224 | useAlignment, : false,
225 | useIndicator : true,
226 | indicatorScaleUpCoefficient : 0.01,
227 | willPeekAndPopComplete : _willPeekAndPopComplete,
228 | willPushPeekAndPop : _willPushPeekAndPop,
229 | willUpdatePeekAndPop : _willUpdatePeekAndPop,
230 | willCancelPeekAndPop : _willCancelPeekAndPop,
231 | willFinishPeekAndPop : _willFinishPeekAndPop,
232 | willClosePeekAndPop : _willClosePeekAndPop,
233 | onPeekAndPopComplete : _onPeekAndPopComplete,
234 | onPushPeekAndPop : _onPushPeekAndPop,
235 | onUpdatePeekAndPop : _onUpdatePeekAndPop,
236 | onCancelPeekAndPop : _onCancelPeekAndPop,
237 | onFinishPeekAndPop : _onFinishPeekAndPop,
238 | onClosePeekAndPop : _onFinishPeekAndPop,
239 | onPressStart : _onPressStart,
240 | onPressUpdate : _onPressUpdate,
241 | onPressEnd : _onPressEnd,
242 | treshold : 0.5,
243 | startPressure : 0.125,
244 | peakPressure : 1.0,
245 | peekScale : 0.5,
246 | peekCoefficient : 0.05,
247 | popTransition,
248 | useHaptics : true})
249 |
250 | Widget uiChild() {}
251 |
252 | Widget peekAndPopBuilderAtPeek(BuildContext context, PeekAndPopControllerState _peekAndPopController);
253 | Widget peekAndPopBuilderAtPop(BuildContext context, PeekAndPopControllerState _peekAndPopController);
254 |
255 | QuickActionsData quickActionsBuilder(PeekAndPopControllerState _peekAndPopController);
256 |
257 | WidgetBuilder overlayBuiler(BuildContext context);
258 |
259 | bool _willPeekAndPopComplete(PeekAndPopControllerState _peekAndPopController);
260 | bool _willPushPeekAndPop(PeekAndPopControllerState _peekAndPopController);
261 | bool _willUpdatePeekAndPop(PeekAndPopControllerState _peekAndPopController);
262 | bool _willCancelPeekAndPop(PeekAndPopControllerState _peekAndPopController);
263 | bool _willFinishPeekAndPop(PeekAndPopControllerState _peekAndPopController);
264 | bool _willClosePeekAndPop(PeekAndPopControllerState _peekAndPopController);
265 |
266 | void _onPeekAndPopComplete(PeekAndPopControllerState _peekAndPopController);
267 | void _onPushPeekAndPop(PeekAndPopControllerState _peekAndPopController);
268 | void _onUpdatePeekAndPop(PeekAndPopControllerState _peekAndPopController);
269 | void _onCancelPeekAndPop(PeekAndPopControllerState _peekAndPopController);
270 | void _onFinishPeekAndPop(PeekAndPopControllerState _peekAndPopController);
271 | void _onClosePeekAndPop(PeekAndPopControllerState _peekAndPopController);
272 |
273 | void _onPressStart(dynamic dragDetails);
274 | void _onPressUpdate(dynamic dragDetails);
275 | void _onPressEnd(dynamic dragDetails);
276 |
277 | ```
278 |
279 | **Further Explanations:**
280 |
281 | *For a complete set of descriptions for all parameters and methods, see the [documentation](https://pub.dev/documentation/peek_and_pop/latest/).*
282 |
283 | * Set [uiChildUseCache] to true if your [uiChild] doesn't change during the Peek & Pop process.
284 | * Set [peekAndPopBuilderUseCache] to true if your [peekAndPopBuilder] doesn't change during the Peek & Pop process.
285 | * If [peekAndPopBuilderAtPop] and [peekAndPopBuilderAtPeek] are set, [peekAndPopBuilder] and [peekAndPopBuilderUseCache] are ignored.
286 | * If one of [peekAndPopBuilderAtPop] and [peekAndPopBuilderAtPeek] is set, the other one must be set too.
287 | * If [quickActionsBuilder] is set, it is recommended that [peekAndPopBuilderAtPop] and [peekAndPopBuilderAtPop] are set too.
288 | * [overlayBuilder] is an optional second view to be displayed during the Peek & Pop process. This entire widget is built after everything else.
289 | * For all [PeekAndPopProcessNotifier] callbacks such as [willPeekAndPopComplete], you can return false to prevent the default action.
290 | * All [PeekAndPopProcessNotifier] and [PeekAndPopProcessCallback] callbacks will return a reference to the created [PeekAndPopController] state.
291 | You can save this instance for further actions.
292 | * [pageTransition] is the transition to be used when the view is opened directly or when the view is closed. A default [SlideTransition] is provided.
293 | * Use [PeekAndPopControllerState]'s [void closePeekAndPop()] method to close the Peek & Pop process. Do not call [Navigator.of(context).pop()]
294 | directly.
295 | * Use [PeekAndPopControllerState]'s [stage] variable to get enumeration for the stage of the Peek & Pop process. If you want to only know when the
296 | Peek & Pop process will be or is completed, you can also use [willBeDone] or [isDone] variables.
297 |
298 |
299 | [comment]: <> (Notes)
300 | ## Notes
301 | I started using and learning Flutter only some weeks ago so this package might have some parts that don't make sense, that should be completely
302 | different, that could be much better, etc. Please let me know! Nicely!
303 |
304 | Any help, suggestion or criticism is appreciated!
305 |
306 | Cheers.
307 |
308 | [comment]: <> (CosmosSoftware)
309 |
310 |
311 |
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/0.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/1.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/1.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/10.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/10.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/11.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/11.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/12.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/12.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/13.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/13.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/14.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/14.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/15.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/15.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/16.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/16.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/17.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/17.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/18.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/18.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/19.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/19.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/2.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/2.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/20.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/20.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/21.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/21.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/22.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/22.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/23.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/23.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/24.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/24.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/25.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/25.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/26.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/26.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/27.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/27.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/28.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/28.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/29.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/29.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/3.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/3.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/4.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/4.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/5.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/5.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/6.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/6.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/7.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/7.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/8.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/8.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/9.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/9.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/Hero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/Hero.png
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/assets/Scenery.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/assets/Scenery.jpeg
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/lib/main.dart:
--------------------------------------------------------------------------------
1 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2 | // © Cosmos Software | Ali Yigit Bireroglu /
3 | // All material used in the making of this code, project, program, application, software et cetera (the "Intellectual Property") /
4 | // belongs completely and solely to Ali Yigit Bireroglu. This includes but is not limited to the source code, the multimedia and /
5 | // other asset files. If you were granted this Intellectual Property for personal use, you are obligated to include this copyright /
6 | // text at all times. /
7 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
8 | //@formatter:off
9 |
10 | import 'package:flutter/foundation.dart';
11 | import 'package:flutter/cupertino.dart';
12 | import 'package:flutter/material.dart';
13 | import 'package:flutter/services.dart';
14 |
15 | import 'nav_bar.dart' as MyNavBar;
16 |
17 | import 'package:peek_and_pop/peek_and_pop.dart';
18 | import 'package:peek_and_pop/misc.dart' as PeekAndPopMisc;
19 |
20 | PeekAndPopControllerState peekAndPopController;
21 |
22 | final GlobalKey scaffold = GlobalKey();
23 | final GlobalKey header = GlobalKey();
24 |
25 | void main() => runApp(MyApp());
26 |
27 | class MyApp extends StatelessWidget {
28 | @override
29 | Widget build(BuildContext context) {
30 | return RepaintBoundary(
31 | key: PeekAndPopMisc.background,
32 | child: MaterialApp(
33 | title: 'Showcase',
34 | home: MyHomePage(title: 'Showcase'),
35 | ),
36 | );
37 | }
38 | }
39 |
40 | class MyHomePage extends StatefulWidget {
41 | MyHomePage({Key key, this.title}) : super(key: key);
42 |
43 | final String title;
44 |
45 | @override
46 | _MyHomePageState createState() => _MyHomePageState();
47 | }
48 |
49 | class _MyHomePageState extends State {
50 | ScrollController scrollController;
51 | ValueNotifier scrollControllerNotifier;
52 | List verticalImages = [2, 3, 7, 15, 17, 18, 21];
53 |
54 | void onScroll() {
55 | scrollControllerNotifier.value = scrollController.offset * 1.0;
56 | }
57 |
58 | @override
59 | void initState() {
60 | super.initState();
61 |
62 | scrollController = ScrollController(initialScrollOffset: 0);
63 | scrollController.addListener(onScroll);
64 | scrollControllerNotifier = ValueNotifier(0.0);
65 | }
66 |
67 | void showSnackbar() {
68 | scaffold.currentState.showSnackBar(SnackBar(content: const Text("Photo is saved your favourites.")));
69 | }
70 |
71 | Widget atPeekWrapper(Widget child, PeekAndPopControllerState _peekAndPopController) {
72 | return Container(
73 | decoration: BoxDecoration(
74 | borderRadius: const BorderRadius.all(const Radius.circular(10.0)),
75 | boxShadow: [
76 | const BoxShadow(
77 | color: Colors.black,
78 | offset: const Offset(0, 15),
79 | spreadRadius: -5,
80 | blurRadius: 20,
81 | ),
82 | ],
83 | ),
84 | child: ClipRRect(
85 | borderRadius: const BorderRadius.all(const Radius.circular(10.0)),
86 | child: child,
87 | ),
88 | );
89 | }
90 |
91 | MyNavBar.CupertinoNavigationBar appBar(PeekAndPopControllerState _peekAndPopController) {
92 | return MyNavBar.CupertinoNavigationBar(
93 | key: header,
94 | backgroundColor: const Color(0xff1B1B1B),
95 | border: const Border(
96 | bottom: const BorderSide(
97 | color: Colors.black,
98 | width: 0.0,
99 | style: BorderStyle.solid,
100 | ),
101 | ),
102 | middle: const Text(
103 | "Photo",
104 | style: const TextStyle(color: const Color(0xffFF9500)),
105 | ),
106 | leading: CupertinoButton(
107 | padding: EdgeInsets.only(bottom: 2),
108 | onPressed: () {
109 | HapticFeedback.mediumImpact();
110 | _peekAndPopController.closePeekAndPop();
111 | },
112 | child: const Icon(
113 | CupertinoIcons.clear_circled,
114 | size: 25,
115 | color: const Color(0xffFF9500),
116 | ),
117 | ),
118 | trailing: CupertinoButton(
119 | padding: EdgeInsets.only(bottom: 2),
120 | onPressed: () {
121 | HapticFeedback.mediumImpact();
122 | showSnackbar();
123 | },
124 | child: const Icon(
125 | CupertinoIcons.heart_solid,
126 | size: 25,
127 | color: const Color(0xffFF9500),
128 | ),
129 | ),
130 | transitionBetweenRoutes: false,
131 | );
132 | }
133 |
134 | Widget atPopWrapper(Widget child, PeekAndPopControllerState _peekAndPopController) {
135 | return Scaffold(
136 | key: scaffold,
137 | backgroundColor: CupertinoColors.darkBackgroundGray,
138 | appBar: appBar(_peekAndPopController),
139 | body: SizedBox.expand(child: child),
140 | );
141 | }
142 |
143 | Widget gridPeekAndPopBuilderAtPeek(int index, BuildContext context, PeekAndPopControllerState _peekAndPopController) {
144 | return atPeekWrapper(
145 | Image.asset(
146 | "assets/" + index.toString() + ".jpeg",
147 | fit: BoxFit.contain,
148 | key: Key("Image"),
149 | scale: verticalImages.contains(index) ? 0.5 : 1.0,
150 | ),
151 | _peekAndPopController,
152 | );
153 | }
154 |
155 | Widget gridPeekAndPopBuilderAtPop(int index, BuildContext context, PeekAndPopControllerState _peekAndPopController) {
156 | return atPopWrapper(
157 | Transform.translate(
158 | offset: Offset(0, verticalImages.contains(index) ? 0.0 : -50),
159 | child: Image.asset(
160 | "assets/" + index.toString() + ".jpeg",
161 | fit: BoxFit.contain,
162 | key: Key("Image"),
163 | ),
164 | ),
165 | _peekAndPopController,
166 | );
167 | }
168 |
169 | QuickActionsData gridQuickActionsBuilder(PeekAndPopControllerState _peekAndPopController) {
170 | return QuickActionsData(
171 | const EdgeInsets.only(left: 12.5, top: 25, right: 12.5, bottom: 25),
172 | const BorderRadius.all(const Radius.circular(10.0)),
173 | [
174 | QuickAction(
175 | 60,
176 | () {
177 | _peekAndPopController.peekAndPopChild.quickActions.currentState.animationController.reverse();
178 | Future.wait([_peekAndPopController.peekAndPopChild.snapController.currentState.move(const Offset(0.0, 0.0))]).then((_) {
179 | _peekAndPopController.finishPeekAndPop(null);
180 | });
181 | },
182 | const BoxDecoration(
183 | color: CupertinoColors.white,
184 | border: const Border(
185 | bottom: const BorderSide(
186 | color: CupertinoColors.inactiveGray,
187 | width: 0.0,
188 | style: BorderStyle.solid,
189 | ),
190 | ),
191 | ),
192 | const Center(
193 | child: const Text(
194 | "Pop",
195 | style: const TextStyle(
196 | color: CupertinoColors.activeBlue,
197 | fontWeight: FontWeight.normal,
198 | fontSize: 20,
199 | ),
200 | textAlign: TextAlign.center,
201 | ),
202 | ),
203 | ),
204 | QuickAction(
205 | 60,
206 | () {},
207 | const BoxDecoration(
208 | color: CupertinoColors.white,
209 | border: const Border(
210 | bottom: const BorderSide(
211 | color: CupertinoColors.inactiveGray,
212 | width: 0.0,
213 | style: BorderStyle.solid,
214 | ),
215 | ),
216 | ),
217 | const Center(
218 | child: const Text(
219 | "Save",
220 | style: const TextStyle(
221 | color: CupertinoColors.activeBlue,
222 | fontWeight: FontWeight.normal,
223 | fontSize: 20,
224 | ),
225 | textAlign: TextAlign.center,
226 | ),
227 | ),
228 | ),
229 | QuickAction(
230 | 60,
231 | () {},
232 | const BoxDecoration(
233 | color: CupertinoColors.white,
234 | border: const Border(
235 | bottom: const BorderSide(
236 | color: CupertinoColors.inactiveGray,
237 | width: 0.0,
238 | style: BorderStyle.solid,
239 | ),
240 | ),
241 | ),
242 | const Center(
243 | child: const Text(
244 | "Share",
245 | style: const TextStyle(
246 | color: CupertinoColors.activeBlue,
247 | fontWeight: FontWeight.normal,
248 | fontSize: 20,
249 | ),
250 | textAlign: TextAlign.center,
251 | ),
252 | ),
253 | ),
254 | QuickAction(
255 | 60,
256 | () {
257 | _peekAndPopController.peekAndPopChild.quickActions.currentState.animationController.reverse();
258 | Future.wait([_peekAndPopController.peekAndPopChild.snapController.currentState.move(const Offset(0.0, 0.0))]).then((_) {
259 | _peekAndPopController.cancelPeekAndPop(null);
260 | });
261 | },
262 | const BoxDecoration(
263 | color: CupertinoColors.white,
264 | ),
265 | const Center(
266 | child: const Text(
267 | "Dismiss",
268 | style: const TextStyle(
269 | color: CupertinoColors.destructiveRed,
270 | fontWeight: FontWeight.normal,
271 | fontSize: 20,
272 | ),
273 | textAlign: TextAlign.center,
274 | ),
275 | ),
276 | ),
277 | ],
278 | );
279 | }
280 |
281 | @override
282 | Widget build(BuildContext context) {
283 | return CupertinoPageScaffold(
284 | backgroundColor: CupertinoColors.darkBackgroundGray,
285 | child: PeekAndPopMisc.scaleDownWrapper(
286 | CustomScrollView(
287 | controller: scrollController,
288 | slivers: [
289 | MyNavBar.CupertinoSliverNavigationBar(
290 | largeTitle: Text(
291 | widget.title,
292 | style: const TextStyle(color: const Color(0xffFF9500)),
293 | ),
294 | backgroundColor: const Color(0xff1B1B1B),
295 | border: const Border(
296 | bottom: const BorderSide(
297 | color: Colors.black,
298 | width: 0.0,
299 | style: BorderStyle.solid,
300 | ),
301 | ),
302 | transitionBetweenRoutes: false,
303 | ),
304 | SliverPadding(
305 | padding: EdgeInsets.all(10),
306 | sliver: SliverGrid.count(
307 | mainAxisSpacing: 10.0,
308 | crossAxisSpacing: 10.0,
309 | crossAxisCount: 3,
310 | children: List.generate(30, (int index) {
311 | return PeekAndPopController(
312 | ValueListenableBuilder(
313 | builder: (BuildContext context, double scrollController, Widget cachedChild) {
314 | double height = MediaQuery.of(context).size.width / 3.0;
315 | double position = index % 3 * height;
316 | double alignment = ((scrollController - position) / (position + height)).clamp(-1.0, 1.0);
317 |
318 | return Container(
319 | decoration: BoxDecoration(
320 | image: DecorationImage(
321 | image: AssetImage(
322 | "assets/" + index.toString() + ".jpeg",
323 | ),
324 | alignment: Alignment(alignment, alignment),
325 | fit: BoxFit.cover,
326 | ),
327 | borderRadius: const BorderRadius.all(const Radius.circular(10.0)),
328 | ),
329 | );
330 | },
331 | valueListenable: scrollControllerNotifier,
332 | ),
333 | true,
334 | peekAndPopBuilderAtPeek: (BuildContext context, PeekAndPopControllerState _peekAndPopController) => gridPeekAndPopBuilderAtPeek(index, context, _peekAndPopController),
335 | peekAndPopBuilderAtPop: (BuildContext context, PeekAndPopControllerState _peekAndPopController) => gridPeekAndPopBuilderAtPop(index, context, _peekAndPopController),
336 | quickActionsBuilder: gridQuickActionsBuilder,
337 | sigma: 10,
338 | backdropColor: Colors.white,
339 | useOverlap: true,
340 | useAlignment: false,
341 | indicatorScaleUpCoefficient: 0.01,
342 | peekScale: 0.95,
343 | peekCoefficient: 0.025,
344 | );
345 | }),
346 | ),
347 | )
348 | ],
349 | ),
350 | 0.04,
351 | ),
352 | );
353 | }
354 | }
355 |
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "2.5.0-nullsafety"
11 | bloc:
12 | dependency: transitive
13 | description:
14 | name: bloc
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "6.0.3"
18 | boolean_selector:
19 | dependency: transitive
20 | description:
21 | name: boolean_selector
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "2.1.0-nullsafety"
25 | characters:
26 | dependency: transitive
27 | description:
28 | name: characters
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "1.1.0-nullsafety.2"
32 | charcode:
33 | dependency: transitive
34 | description:
35 | name: charcode
36 | url: "https://pub.dartlang.org"
37 | source: hosted
38 | version: "1.2.0-nullsafety"
39 | clock:
40 | dependency: transitive
41 | description:
42 | name: clock
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "1.1.0-nullsafety"
46 | collection:
47 | dependency: transitive
48 | description:
49 | name: collection
50 | url: "https://pub.dartlang.org"
51 | source: hosted
52 | version: "1.15.0-nullsafety.2"
53 | cupertino_icons:
54 | dependency: "direct main"
55 | description:
56 | name: cupertino_icons
57 | url: "https://pub.dartlang.org"
58 | source: hosted
59 | version: "0.1.2"
60 | fake_async:
61 | dependency: transitive
62 | description:
63 | name: fake_async
64 | url: "https://pub.dartlang.org"
65 | source: hosted
66 | version: "1.1.0-nullsafety"
67 | flick:
68 | dependency: transitive
69 | description:
70 | name: flick
71 | url: "https://pub.dartlang.org"
72 | source: hosted
73 | version: "1.0.2"
74 | flutter:
75 | dependency: "direct main"
76 | description: flutter
77 | source: sdk
78 | version: "0.0.0"
79 | flutter_test:
80 | dependency: "direct dev"
81 | description: flutter
82 | source: sdk
83 | version: "0.0.0"
84 | matcher:
85 | dependency: transitive
86 | description:
87 | name: matcher
88 | url: "https://pub.dartlang.org"
89 | source: hosted
90 | version: "0.12.10-nullsafety"
91 | meta:
92 | dependency: transitive
93 | description:
94 | name: meta
95 | url: "https://pub.dartlang.org"
96 | source: hosted
97 | version: "1.3.0-nullsafety.2"
98 | path:
99 | dependency: transitive
100 | description:
101 | name: path
102 | url: "https://pub.dartlang.org"
103 | source: hosted
104 | version: "1.8.0-nullsafety"
105 | peek_and_pop:
106 | dependency: "direct main"
107 | description:
108 | path: ".."
109 | relative: true
110 | source: path
111 | version: "1.0.3"
112 | sky_engine:
113 | dependency: transitive
114 | description: flutter
115 | source: sdk
116 | version: "0.0.99"
117 | snap:
118 | dependency: transitive
119 | description:
120 | name: snap
121 | url: "https://pub.dartlang.org"
122 | source: hosted
123 | version: "1.0.4"
124 | source_span:
125 | dependency: transitive
126 | description:
127 | name: source_span
128 | url: "https://pub.dartlang.org"
129 | source: hosted
130 | version: "1.8.0-nullsafety"
131 | stack_trace:
132 | dependency: transitive
133 | description:
134 | name: stack_trace
135 | url: "https://pub.dartlang.org"
136 | source: hosted
137 | version: "1.10.0-nullsafety"
138 | stream_channel:
139 | dependency: transitive
140 | description:
141 | name: stream_channel
142 | url: "https://pub.dartlang.org"
143 | source: hosted
144 | version: "2.1.0-nullsafety"
145 | string_scanner:
146 | dependency: transitive
147 | description:
148 | name: string_scanner
149 | url: "https://pub.dartlang.org"
150 | source: hosted
151 | version: "1.1.0-nullsafety"
152 | term_glyph:
153 | dependency: transitive
154 | description:
155 | name: term_glyph
156 | url: "https://pub.dartlang.org"
157 | source: hosted
158 | version: "1.2.0-nullsafety"
159 | test_api:
160 | dependency: transitive
161 | description:
162 | name: test_api
163 | url: "https://pub.dartlang.org"
164 | source: hosted
165 | version: "0.2.19-nullsafety"
166 | transparent_image:
167 | dependency: transitive
168 | description:
169 | name: transparent_image
170 | url: "https://pub.dartlang.org"
171 | source: hosted
172 | version: "1.0.0"
173 | typed_data:
174 | dependency: transitive
175 | description:
176 | name: typed_data
177 | url: "https://pub.dartlang.org"
178 | source: hosted
179 | version: "1.3.0-nullsafety.2"
180 | vector_math:
181 | dependency: transitive
182 | description:
183 | name: vector_math
184 | url: "https://pub.dartlang.org"
185 | source: hosted
186 | version: "2.1.0-nullsafety.2"
187 | webview_flutter:
188 | dependency: "direct main"
189 | description:
190 | name: webview_flutter
191 | url: "https://pub.dartlang.org"
192 | source: hosted
193 | version: "0.3.13"
194 | sdks:
195 | dart: ">=2.10.0-0.0.dev <2.10.0"
196 | flutter: ">=1.5.0 <2.0.0"
197 |
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name : pretty_example
2 | description : Pretty Example Project for peek_and_pop.
3 | version : 1.0.3
4 | author : Ali Yigit Bireroglu
5 | repository : https://github.com/aliyigitbireroglu/flutter-peek-and-pop
6 | homepage : https://www.cosmossoftware.coffee
7 |
8 | environment :
9 | sdk: ">=2.1.0 <3.0.0"
10 |
11 | dependencies :
12 | flutter :
13 | sdk: flutter
14 | peek_and_pop :
15 | path: ../
16 | cupertino_icons: ^0.1.2
17 | webview_flutter: ^0.3.13
18 |
19 | dev_dependencies:
20 | flutter_test:
21 | sdk: flutter
22 |
23 | flutter :
24 | uses-material-design: true
25 |
26 | assets :
27 | - assets/
28 |
--------------------------------------------------------------------------------
/peek_and_pop/pretty_example/test/pretty_example_test.dart:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/pretty_example/test/pretty_example_test.dart
--------------------------------------------------------------------------------
/peek_and_pop/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "2.5.0-nullsafety"
11 | bloc:
12 | dependency: "direct main"
13 | description:
14 | name: bloc
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "6.0.3"
18 | boolean_selector:
19 | dependency: transitive
20 | description:
21 | name: boolean_selector
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "2.1.0-nullsafety"
25 | characters:
26 | dependency: transitive
27 | description:
28 | name: characters
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "1.1.0-nullsafety.2"
32 | charcode:
33 | dependency: transitive
34 | description:
35 | name: charcode
36 | url: "https://pub.dartlang.org"
37 | source: hosted
38 | version: "1.2.0-nullsafety"
39 | clock:
40 | dependency: transitive
41 | description:
42 | name: clock
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "1.1.0-nullsafety"
46 | collection:
47 | dependency: transitive
48 | description:
49 | name: collection
50 | url: "https://pub.dartlang.org"
51 | source: hosted
52 | version: "1.15.0-nullsafety.2"
53 | fake_async:
54 | dependency: transitive
55 | description:
56 | name: fake_async
57 | url: "https://pub.dartlang.org"
58 | source: hosted
59 | version: "1.1.0-nullsafety"
60 | flick:
61 | dependency: transitive
62 | description:
63 | name: flick
64 | url: "https://pub.dartlang.org"
65 | source: hosted
66 | version: "1.0.3"
67 | flutter:
68 | dependency: "direct main"
69 | description: flutter
70 | source: sdk
71 | version: "0.0.0"
72 | flutter_test:
73 | dependency: "direct dev"
74 | description: flutter
75 | source: sdk
76 | version: "0.0.0"
77 | matcher:
78 | dependency: transitive
79 | description:
80 | name: matcher
81 | url: "https://pub.dartlang.org"
82 | source: hosted
83 | version: "0.12.10-nullsafety"
84 | meta:
85 | dependency: transitive
86 | description:
87 | name: meta
88 | url: "https://pub.dartlang.org"
89 | source: hosted
90 | version: "1.3.0-nullsafety.2"
91 | path:
92 | dependency: transitive
93 | description:
94 | name: path
95 | url: "https://pub.dartlang.org"
96 | source: hosted
97 | version: "1.8.0-nullsafety"
98 | sky_engine:
99 | dependency: transitive
100 | description: flutter
101 | source: sdk
102 | version: "0.0.99"
103 | snap:
104 | dependency: "direct main"
105 | description:
106 | name: snap
107 | url: "https://pub.dartlang.org"
108 | source: hosted
109 | version: "1.0.5"
110 | source_span:
111 | dependency: transitive
112 | description:
113 | name: source_span
114 | url: "https://pub.dartlang.org"
115 | source: hosted
116 | version: "1.8.0-nullsafety"
117 | stack_trace:
118 | dependency: transitive
119 | description:
120 | name: stack_trace
121 | url: "https://pub.dartlang.org"
122 | source: hosted
123 | version: "1.10.0-nullsafety"
124 | stream_channel:
125 | dependency: transitive
126 | description:
127 | name: stream_channel
128 | url: "https://pub.dartlang.org"
129 | source: hosted
130 | version: "2.1.0-nullsafety"
131 | string_scanner:
132 | dependency: transitive
133 | description:
134 | name: string_scanner
135 | url: "https://pub.dartlang.org"
136 | source: hosted
137 | version: "1.1.0-nullsafety"
138 | term_glyph:
139 | dependency: transitive
140 | description:
141 | name: term_glyph
142 | url: "https://pub.dartlang.org"
143 | source: hosted
144 | version: "1.2.0-nullsafety"
145 | test_api:
146 | dependency: transitive
147 | description:
148 | name: test_api
149 | url: "https://pub.dartlang.org"
150 | source: hosted
151 | version: "0.2.19-nullsafety"
152 | transparent_image:
153 | dependency: "direct main"
154 | description:
155 | name: transparent_image
156 | url: "https://pub.dartlang.org"
157 | source: hosted
158 | version: "1.0.0"
159 | typed_data:
160 | dependency: transitive
161 | description:
162 | name: typed_data
163 | url: "https://pub.dartlang.org"
164 | source: hosted
165 | version: "1.3.0-nullsafety.2"
166 | vector_math:
167 | dependency: transitive
168 | description:
169 | name: vector_math
170 | url: "https://pub.dartlang.org"
171 | source: hosted
172 | version: "2.1.0-nullsafety.2"
173 | sdks:
174 | dart: ">=2.10.0-0.0.dev <2.10.0"
175 |
--------------------------------------------------------------------------------
/peek_and_pop/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name : peek_and_pop
2 | description : Peek & Pop implementation for Flutter based on the iOS functionality of the same name.
3 | version : 1.0.3
4 | author : Ali Yigit Bireroglu
5 | repository : https://github.com/aliyigitbireroglu/flutter-peek-and-pop
6 | homepage : https://www.cosmossoftware.coffee
7 |
8 | environment :
9 | sdk: ">=2.8.0 <3.0.0"
10 |
11 | dependencies :
12 | flutter :
13 | sdk: flutter
14 | snap : ^1.0.5
15 | transparent_image: ^1.0.0
16 | bloc : ^6.0.3
17 |
18 | dev_dependencies:
19 | flutter_test:
20 | sdk: flutter
21 |
22 | flutter :
23 |
--------------------------------------------------------------------------------
/peek_and_pop/test/peek_and_pop_test.dart:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aliyigitbireroglu/flutter-peek-and-pop/232534da374a0babeb2a077a60b8e809e64cd8a1/peek_and_pop/test/peek_and_pop_test.dart
--------------------------------------------------------------------------------