peek_and_pop 0.2.0+1

peek_and_pop #

Cosmos Software Awesome Flutter

Pub License

Peek & Pop implementation for Flutter based on the iOS functionality of the same name.

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 capabilities.

Media | Description | Installation | How-to-Use

Notice #

  • v0.1.9 no longer requires any modifications to Flutter's normal "binding.dart"! You can leave your Flutter source code alone and happy.

  • If you are updating from an earlier version, you can revert your "binding.dart" to its original format.


Recent #

  • The "Indicator" feature is now added. See Media for examples.

  • Animations are now up to 4x faster with the new optimised blur effect algorithm during the Peek & Pop process.


Media #

Watch on Youtube:

v0.1.7

v0.1.0 Mixed v0.0.1 Normal | v0.0.1 Moveable | v0.0.1 Platform View | v0.0.1 Hero



Description #

As a fan of the iOS Peek & Pop functionality, I decided to implement it for Flutter as well.

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 this would be appreciated.

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 still under development and is not yet fully tested so consider it as a developers preview.

## The power move of this package is what I like to call "Gesture Recognition Rerouting". Normally, when a new widget with GestureDetector or similar 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 for Flutter to resume updating it. This package fixes that problem as explained in the documentation:

//This function is called by the instantiated [PeekAndPopChild] once it is ready to be included in the Peek & Pop process. Perhaps the most
//essential functionality of this package also takes places in this function: The gesture recognition is rerouted from the [PeekAndPopDetector]
//to the instantiated [PeekAndPopChild]. This is important for avoiding the necessity of having the user stop and restart their Force Press.
//Instead, the [PeekAndPopController] does this automatically so that the existing Force Press can continue to update even when if
//[PeekAndPopDetector] is blocked by the view which is often the case especially when using PlatformViews.

Installation #

It is easy. Don't worry.

If you do not wish to use PlatformViews and if you are using a version of this package equal to or newer than v0.1.9, you can skip the installation instructions. Installation instructions will soon be removed.

  • Step I (Optional) For properly displaying PlatformViews, this package requires the latest Flutter master branch. Maybe it will work with some other version too but tests made with the webview_flutter seem to only properly display with the latest Flutter master branch which has improved the PlatformViews that allow better functionalities such as proper scaling and proper clipping.

    If you do not wish to use PlatformViews, you can skip this step.

    To use latest Flutter master branch, run the following command and then run the Flutter doctor. That's it, it should be fine.

    Note: Don't forget to add to your Info.plist. See webview_flutter for more info.

$ git clone -b master https://github.com/flutter/flutter.git
$ ./flutter/bin/flutter --version
  • Step II (Required ONLY for versions older than v0.1.9) This package uses a modified version of Flutter's normal "binding.dart". Nothing essential is changed so do not worry about the edited file interfering with your projects. The modifications are mostly about exposing variables that are by default private. The new "binding.dart" is otherwise identical to Flutter's normal "binding.dart".

    Overwrite the contents of

    (your_flutter_directory)/packages/flutter/lib/src/gestures/binding.dart

    with the contents of "binding.dart" provided by this package. Then uncomment the parts marked "UNCOMMENT HERE" in "peek_and_pop_controller.dart". These parts had to be commented for cosmetic reasons as Pub considers them to be errors due to the previously explained "binding.dart" modifications.

How-to-Use #

Also easy.

First of all, as explained in the documentation:

//I noticed that a fullscreen blur effect via the [BackdropFilter] widget is not good to use while running the animations required for the Peek &
//Pop process as it causes a noticeable drop in the framerate- especially for devices with high resolutions. During a mostly static view, the
//drop is acceptable. However, once the animations start running, this drop causes a visual disturbance. To prevent this, a new optimised blur
//effect algorithm is implemented. Now, the [BackdropFilter] widget is only used until the animations are about to start. At that moment, it is
//replaced by a static image. Therefore, to capture this image, your root CupertinoApp/MaterialApp MUST be wrapped in a [RepaintBoundary] widget
//which uses the [background] key. As a result, the Peek & Pop process is now up to 4x more fluent.

TL;DR: Wrap your root CupertinoApp/MaterialApp in a RepaintBoundary widget and use the background GlobalKey from "misc.dart".

This is required for the new optimised blur effect algorithm:

import 'package:peek_and_pop/misc.dart' as PeekAndPopMisc;

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RepaintBoundary(
      key: PeekAndPopMisc.background,
      child: MaterialApp(
        title: 'Peek & Pop Demo',
        home: MyHomePage(title: 'Peek & Pop Demo')
      )
    );
  }
}

Then, create a PeekAndPopController such as:

PeekAndPopController(
  uiChild(),            //Widget uiChild
  peekAndPopBuilder,    //PeekAndPopBuilder peekAndPopBuilder
  false,                //bool useCache
 {sigma                 : 10,
  backdropColor         : Colors.black,
  alpha                 : 126,
  overlayBuilder,
  useIndicator          : true,
  isHero                : false,
  willPeekAndPopComplete: _willPeekAndPopComplete,
  willPushPeekAndPop    : _willPushPeekAndPop,
  willUpdatePeekAndPop  : _willUpdatePeekAndPop,
  willCancelPeekAndPop  : _willCancelPeekAndPop,
  willFinishPeekAndPop  : _willFinishPeekAndPop,
  willClosePeekAndPop   : _willClosePeekAndPop,
  onPeekAndPopComplete  : _onPeekAndPopComplete,
  onPushPeekAndPop      : _onPushPeekAndPop,
  onUpdatePeekAndPop    : _onUpdatePeekAndPop,
  onCancelPeekAndPop    : _onCancelPeekAndPop,
  onFinishPeekAndPop    : _onFinishPeekAndPop,
  onClosePeekAndPop     : _onFinishPeekAndPop,
  onPressStart          : _onPressStart,
  onPressUpdate         : _onPressUpdate,
  onPressEnd            : _onPressEnd,
  treshold              : 0.5,
  startPressure         : 0.125,
  peakPressure          : 1.0,
  peekScale             : 0.5,
  peekCoefficient       : 0.05,
  popTransition})
  
Widget uiChild() {}

Widget peekAndPopBuilder(BuildContext context, PeekAndPopControllerState _peekAndPopController);

bool _willPeekAndPopComplete(PeekAndPopControllerState _peekAndPopController);
bool _willPushPeekAndPop(PeekAndPopControllerState _peekAndPopController);
bool _willUpdatePeekAndPop(PeekAndPopControllerState _peekAndPopController);
bool _willCancelPeekAndPop(PeekAndPopControllerState _peekAndPopController);
bool _willFinishPeekAndPop(PeekAndPopControllerState _peekAndPopController);
bool _willClosePeekAndPop(PeekAndPopControllerState _peekAndPopController);

void _onPeekAndPopComplete(PeekAndPopControllerState _peekAndPopController);
void _onPushPeekAndPop(PeekAndPopControllerState _peekAndPopController);
void _onUpdatePeekAndPop(PeekAndPopControllerState _peekAndPopController);
void _onCancelPeekAndPop(PeekAndPopControllerState _peekAndPopController);
void _onFinishPeekAndPop(PeekAndPopControllerState _peekAndPopController);
void _onClosePeekAndPop(PeekAndPopControllerState _peekAndPopController);

void _onPressStart(dynamic dragDetails);
void _onPressUpdate(dynamic dragDetails);
void _onPressEnd(dynamic dragDetails);
 

Further Explanations:

For a complete set of descriptions for all parameters and methods, see the documentation.

  • Set [useCache] to true if your [peekAndPopBuilder] doesn't change during the Peek & Pop process.
  • [overlayBuilder] is an optional second view to be displayed during the Peek & Pop process. This entire widget is built after everything else.
  • For all [PeekAndPopProcessNotifier] callbacks such as [willPeekAndPopComplete], you can return false to prevent the default action.
  • All [PeekAndPopProcessNotifier] and [PeekAndPopProcessCallback] callbacks will return a reference to the created [PeekAndPopController] state. You can save this instance for further actions.
  • [popTransition] is the transition to be used when the view is opened directly or when the view is closed. A default [SlideTransition] is provided.
  • Use [PeekAndPopControllerState]'s [void closePeekAndPop()] method to close the Peek & Pop process. Do not call [Navigator.of(context).pop()] directly.
  • Use [PeekAndPopControllerState]'s [Stage get stage] method to get enumeration for the stage of the Peek & Pop process.
  • I realised that when an [AppBar] or a [CupertinoNavigationBar] is built with full transparency, their height is not included in the layout of a [Scaffold] or a [CupertinoPageScaffold]. Therefore, moving from a Peek stage with a transparent header to a Pop stage with a non-transparent header causes visual conflicts. Use this [PeekAndPopChildState]'s [Size get headerSize] and [double getHeaderOffset(HeaderOffset headerOffset)] methods to overcome this problem.

Notes #

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 different, that could be much better, etc. Please let me know! Nicely!

Any help, suggestion or criticism is appreciated!

Cheers.





[0.2.0] - 23.08.2019

  • Improved performance.

  • Minor changes.

  • Improved code style with trailing commas.

  • [0.2.0+1] Minor changes.

[0.1.9] - 20.08.2019

  • Modifications to Flutter's normal "binding.dart" are no longer required!

  • The Long Press version is temporarily removed. It will be added back with the next update.

  • Code excerpt added to the README.

  • Updated README.

  • [0.1.9+1] Updated README.

[0.1.8] - 18.08.2019

  • Example project adapted to the updated snap.

  • Minor changes.

  • [0.1.8+1] Updated README.

[0.1.7] - 14.08.2019

  • The "Indicator" feature added. See this video for examples.

  • Improved performance.

  • Fine tuning.

[0.1.6] - 12.08.2019

  • Improved Long Press version (still under development).

  • Fine tuning.

  • Improved documentation.

  • Updated README.

[0.1.5] - 11.08.2019

  • Improved performance.

  • Improved code style.

[0.1.4] - 11.08.2019

  • A minor bug is fixed.

[0.1.3] - 07.08.2019

  • A minor bug in the example project is fixed.

  • Updated README:

    Note: Don't forget to add to your Info.plist. See webview_flutter for more info.

[0.1.2] - 07.08.2019

  • snap is now implemented directly to the example.

  • More callbacks added for better control.

  • Simple enumeration for the stage of the Peek & Pop process added.

  • Improved animations.

  • Improved documentation.

[0.1.1] - 06.08.2019

  • Improved code style.

[0.1.0] - 06.08.2019

  • Improved Long Press version (still under development).

  • Improved documentation.

[0.0.1] - 05.08.2019

  • Initial release.

example/README.md

example #

Example Project for peek_and_pop.

Note: Don't forget to add to your Info.plist. See webview_flutter for more info.

peek_and_pop #

Cosmos Software Awesome Flutter

Pub License

Peek & Pop implementation for Flutter based on the iOS functionality of the same name.

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 capabilities.

Media | Description | Installation | How-to-Use

Notice #

  • v0.1.9 no longer requires any modifications to Flutter's normal "binding.dart"! You can leave your Flutter source code alone and happy.

  • If you are updating from an earlier version, you can revert your "binding.dart" to its original format.


Recent #

  • The "Indicator" feature is now added. See Media for examples.

  • Animations are now up to 4x faster with the new optimised blur effect algorithm during the Peek & Pop process.


Media #

Watch on Youtube:

v0.1.7

v0.1.0 Mixed v0.0.1 Normal | v0.0.1 Moveable | v0.0.1 Platform View | v0.0.1 Hero



Description #

As a fan of the iOS Peek & Pop functionality, I decided to implement it for Flutter as well.

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 this would be appreciated.

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 still under development and is not yet fully tested so consider it as a developers preview.

## The power move of this package is what I like to call "Gesture Recognition Rerouting". Normally, when a new widget with GestureDetector or similar 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 for Flutter to resume updating it. This package fixes that problem as explained in the documentation:

//This function is called by the instantiated [PeekAndPopChild] once it is ready to be included in the Peek & Pop process. Perhaps the most
//essential functionality of this package also takes places in this function: The gesture recognition is rerouted from the [PeekAndPopDetector]
//to the instantiated [PeekAndPopChild]. This is important for avoiding the necessity of having the user stop and restart their Force Press.
//Instead, the [PeekAndPopController] does this automatically so that the existing Force Press can continue to update even when if
//[PeekAndPopDetector] is blocked by the view which is often the case especially when using PlatformViews.

Installation #

It is easy. Don't worry.

If you do not wish to use PlatformViews and if you are using a version of this package equal to or newer than v0.1.9, you can skip the installation instructions. Installation instructions will soon be removed.

  • Step I (Optional) For properly displaying PlatformViews, this package requires the latest Flutter master branch. Maybe it will work with some other version too but tests made with the webview_flutter seem to only properly display with the latest Flutter master branch which has improved the PlatformViews that allow better functionalities such as proper scaling and proper clipping.

    If you do not wish to use PlatformViews, you can skip this step.

    To use latest Flutter master branch, run the following command and then run the Flutter doctor. That's it, it should be fine.

    Note: Don't forget to add to your Info.plist. See webview_flutter for more info.

$ git clone -b master https://github.com/flutter/flutter.git
$ ./flutter/bin/flutter --version
  • Step II (Required ONLY for versions older than v0.1.9) This package uses a modified version of Flutter's normal "binding.dart". Nothing essential is changed so do not worry about the edited file interfering with your projects. The modifications are mostly about exposing variables that are by default private. The new "binding.dart" is otherwise identical to Flutter's normal "binding.dart".

    Overwrite the contents of

    (your_flutter_directory)/packages/flutter/lib/src/gestures/binding.dart

    with the contents of "binding.dart" provided by this package. Then uncomment the parts marked "UNCOMMENT HERE" in "peek_and_pop_controller.dart". These parts had to be commented for cosmetic reasons as Pub considers them to be errors due to the previously explained "binding.dart" modifications.

How-to-Use #

Also easy.

First of all, as explained in the documentation:

//I noticed that a fullscreen blur effect via the [BackdropFilter] widget is not good to use while running the animations required for the Peek &
//Pop process as it causes a noticeable drop in the framerate- especially for devices with high resolutions. During a mostly static view, the
//drop is acceptable. However, once the animations start running, this drop causes a visual disturbance. To prevent this, a new optimised blur
//effect algorithm is implemented. Now, the [BackdropFilter] widget is only used until the animations are about to start. At that moment, it is
//replaced by a static image. Therefore, to capture this image, your root CupertinoApp/MaterialApp MUST be wrapped in a [RepaintBoundary] widget
//which uses the [background] key. As a result, the Peek & Pop process is now up to 4x more fluent.

TL;DR: Wrap your root CupertinoApp/MaterialApp in a RepaintBoundary widget and use the background GlobalKey from "misc.dart".

This is required for the new optimised blur effect algorithm:

import 'package:peek_and_pop/misc.dart' as PeekAndPopMisc;

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RepaintBoundary(
      key: PeekAndPopMisc.background,
      child: MaterialApp(
        title: 'Peek & Pop Demo',
        home: MyHomePage(title: 'Peek & Pop Demo')
      )
    );
  }
}

Then, create a PeekAndPopController such as:

PeekAndPopController(
  uiChild(),            //Widget uiChild
  peekAndPopBuilder,    //PeekAndPopBuilder peekAndPopBuilder
  false,                //bool useCache
 {sigma                 : 10,
  backdropColor         : Colors.black,
  alpha                 : 126,
  overlayBuilder,
  useIndicator          : true,
  isHero                : false,
  willPeekAndPopComplete: _willPeekAndPopComplete,
  willPushPeekAndPop    : _willPushPeekAndPop,
  willUpdatePeekAndPop  : _willUpdatePeekAndPop,
  willCancelPeekAndPop  : _willCancelPeekAndPop,
  willFinishPeekAndPop  : _willFinishPeekAndPop,
  willClosePeekAndPop   : _willClosePeekAndPop,
  onPeekAndPopComplete  : _onPeekAndPopComplete,
  onPushPeekAndPop      : _onPushPeekAndPop,
  onUpdatePeekAndPop    : _onUpdatePeekAndPop,
  onCancelPeekAndPop    : _onCancelPeekAndPop,
  onFinishPeekAndPop    : _onFinishPeekAndPop,
  onClosePeekAndPop     : _onFinishPeekAndPop,
  onPressStart          : _onPressStart,
  onPressUpdate         : _onPressUpdate,
  onPressEnd            : _onPressEnd,
  treshold              : 0.5,
  startPressure         : 0.125,
  peakPressure          : 1.0,
  peekScale             : 0.5,
  peekCoefficient       : 0.05,
  popTransition})
  
Widget uiChild() {}

Widget peekAndPopBuilder(BuildContext context, PeekAndPopControllerState _peekAndPopController);

bool _willPeekAndPopComplete(PeekAndPopControllerState _peekAndPopController);
bool _willPushPeekAndPop(PeekAndPopControllerState _peekAndPopController);
bool _willUpdatePeekAndPop(PeekAndPopControllerState _peekAndPopController);
bool _willCancelPeekAndPop(PeekAndPopControllerState _peekAndPopController);
bool _willFinishPeekAndPop(PeekAndPopControllerState _peekAndPopController);
bool _willClosePeekAndPop(PeekAndPopControllerState _peekAndPopController);

void _onPeekAndPopComplete(PeekAndPopControllerState _peekAndPopController);
void _onPushPeekAndPop(PeekAndPopControllerState _peekAndPopController);
void _onUpdatePeekAndPop(PeekAndPopControllerState _peekAndPopController);
void _onCancelPeekAndPop(PeekAndPopControllerState _peekAndPopController);
void _onFinishPeekAndPop(PeekAndPopControllerState _peekAndPopController);
void _onClosePeekAndPop(PeekAndPopControllerState _peekAndPopController);

void _onPressStart(dynamic dragDetails);
void _onPressUpdate(dynamic dragDetails);
void _onPressEnd(dynamic dragDetails);
 

Further Explanations:

For a complete set of descriptions for all parameters and methods, see the documentation.

  • Set [useCache] to true if your [peekAndPopBuilder] doesn't change during the Peek & Pop process.
  • [overlayBuilder] is an optional second view to be displayed during the Peek & Pop process. This entire widget is built after everything else.
  • For all [PeekAndPopProcessNotifier] callbacks such as [willPeekAndPopComplete], you can return false to prevent the default action.
  • All [PeekAndPopProcessNotifier] and [PeekAndPopProcessCallback] callbacks will return a reference to the created [PeekAndPopController] state. You can save this instance for further actions.
  • [popTransition] is the transition to be used when the view is opened directly or when the view is closed. A default [SlideTransition] is provided.
  • Use [PeekAndPopControllerState]'s [void closePeekAndPop()] method to close the Peek & Pop process. Do not call [Navigator.of(context).pop()] directly.
  • Use [PeekAndPopControllerState]'s [Stage get stage] method to get enumeration for the stage of the Peek & Pop process.
  • I realised that when an [AppBar] or a [CupertinoNavigationBar] is built with full transparency, their height is not included in the layout of a [Scaffold] or a [CupertinoPageScaffold]. Therefore, moving from a Peek stage with a transparent header to a Pop stage with a non-transparent header causes visual conflicts. Use this [PeekAndPopChildState]'s [Size get headerSize] and [double getHeaderOffset(HeaderOffset headerOffset)] methods to overcome this problem.

Notes #

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 different, that could be much better, etc. Please let me know! Nicely!

Any help, suggestion or criticism is appreciated!

Cheers.





Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  peek_and_pop: ^0.2.0+1

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:peek_and_pop/peek_and_pop.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
39
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
70
Learn more about scoring.

We analyzed this package on Aug 23, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.4.0
  • pana: 0.12.19
  • Flutter: 1.7.8+hotfix.4

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Health suggestions

Format lib/gesture_detector.dart.

Run flutter format to format lib/gesture_detector.dart.

Format lib/misc.dart.

Run flutter format to format lib/misc.dart.

Format lib/peek_and_pop_child.dart.

Run flutter format to format lib/peek_and_pop_child.dart.

Format lib/peek_and_pop_controller.dart.

Run flutter format to format lib/peek_and_pop_controller.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.2.2 <3.0.0
flutter 0.0.0
transparent_image ^1.0.0 1.0.0
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.6 1.1.7
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test