diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5787014..52cb0d5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 0.2.0
+* Migrated to Null Safety
+
 ## 0.1.3
 
 * Migrated to AndroidX
diff --git a/example/pubspec.lock b/example/pubspec.lock
index 4e0b4df..60535d5 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -1,62 +1,48 @@
 # Generated by pub
 # See https://dart.dev/tools/pub/glossary#lockfile
 packages:
-  archive:
-    dependency: transitive
-    description:
-      name: archive
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "2.0.11"
-  args:
-    dependency: transitive
-    description:
-      name: args
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "1.5.2"
   async:
     dependency: transitive
     description:
       name: async
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.4.0"
+    version: "2.5.0"
   boolean_selector:
     dependency: transitive
     description:
       name: boolean_selector
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.0.5"
-  charcode:
+    version: "2.1.0"
+  characters:
     dependency: transitive
     description:
-      name: charcode
+      name: characters
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.2"
-  collection:
+    version: "1.1.0"
+  charcode:
     dependency: transitive
     description:
-      name: collection
+      name: charcode
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.14.11"
-  convert:
+    version: "1.2.0"
+  clock:
     dependency: transitive
     description:
-      name: convert
+      name: clock
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.1.1"
-  crypto:
+    version: "1.1.0"
+  collection:
     dependency: transitive
     description:
-      name: crypto
+      name: collection
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.1.3"
+    version: "1.15.0"
   cupertino_icons:
     dependency: "direct main"
     description:
@@ -64,6 +50,13 @@ packages:
       url: "https://pub.dartlang.org"
     source: hosted
     version: "0.1.2"
+  fake_async:
+    dependency: transitive
+    description:
+      name: fake_async
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.2.0"
   flutter:
     dependency: "direct main"
     description: flutter
@@ -75,61 +68,33 @@ packages:
       path: ".."
       relative: true
     source: path
-    version: "0.1.2"
+    version: "0.2.0"
   flutter_test:
     dependency: "direct dev"
     description: flutter
     source: sdk
     version: "0.0.0"
-  image:
-    dependency: transitive
-    description:
-      name: image
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "2.1.4"
   matcher:
     dependency: transitive
     description:
       name: matcher
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.12.6"
+    version: "0.12.10"
   meta:
     dependency: transitive
     description:
       name: meta
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.8"
+    version: "1.3.0"
   path:
     dependency: transitive
     description:
       name: path
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.6.4"
-  pedantic:
-    dependency: transitive
-    description:
-      name: pedantic
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "1.8.0+1"
-  petitparser:
-    dependency: transitive
-    description:
-      name: petitparser
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "2.4.0"
-  quiver:
-    dependency: transitive
-    description:
-      name: quiver
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "2.0.5"
+    version: "1.8.0"
   sky_engine:
     dependency: transitive
     description: flutter
@@ -141,62 +106,55 @@ packages:
       name: source_span
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.5.5"
+    version: "1.8.0"
   stack_trace:
     dependency: transitive
     description:
       name: stack_trace
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.9.3"
+    version: "1.10.0"
   stream_channel:
     dependency: transitive
     description:
       name: stream_channel
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.0.0"
+    version: "2.1.0"
   string_scanner:
     dependency: transitive
     description:
       name: string_scanner
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.0.5"
+    version: "1.1.0"
   term_glyph:
     dependency: transitive
     description:
       name: term_glyph
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.0"
+    version: "1.2.0"
   test_api:
     dependency: transitive
     description:
       name: test_api
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.2.11"
+    version: "0.2.19"
   typed_data:
     dependency: transitive
     description:
       name: typed_data
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.6"
+    version: "1.3.0"
   vector_math:
     dependency: transitive
     description:
       name: vector_math
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.0.8"
-  xml:
-    dependency: transitive
-    description:
-      name: xml
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "3.5.0"
+    version: "2.1.0"
 sdks:
-  dart: ">=2.4.0 <3.0.0"
+  dart: ">=2.12.0 <3.0.0"
diff --git a/example/pubspec.yaml b/example/pubspec.yaml
index eaa216c..d4603e0 100644
--- a/example/pubspec.yaml
+++ b/example/pubspec.yaml
@@ -4,7 +4,7 @@ publish_to: 'none'
 version: 0.0.1+1
 
 environment:
-  sdk: ">=2.1.0 <3.0.0"
+  sdk: '>=2.12.0 <3.0.0'
 
 dependencies:
   flutter:
diff --git a/lib/src/channel_manager.dart b/lib/src/channel_manager.dart
index 51adf46..4aa8246 100644
--- a/lib/src/channel_manager.dart
+++ b/lib/src/channel_manager.dart
@@ -19,13 +19,11 @@ class ChannelManager {
     await _channel.invokeMethod('animate', animate);
   }
 
-  static Future<bool> expand() async {
-    return await _channel.invokeMethod('expand');
-  }
+  static Future<bool> expand() =>
+      _channel.invokeMethod<bool>('expand').then((x) => x ?? false);
 
-  static Future<bool> fling(double velocity) async {
-    return await _channel.invokeMethod('fling', velocity);
-  }
+  static Future<bool> fling(double velocity) =>
+      _channel.invokeMethod<bool>('fling', velocity).then((x) => x ?? false);
 
   static Future<void> updateScroll(double position) async {
     await _channel.invokeMethod('updateScroll', position);
diff --git a/lib/src/keyboard_manager.dart b/lib/src/keyboard_manager.dart
index 7a562b6..b2978a2 100644
--- a/lib/src/keyboard_manager.dart
+++ b/lib/src/keyboard_manager.dart
@@ -6,25 +6,28 @@ import 'package:flutter_interactive_keyboard/src/channel_receiver.dart';
 import 'channel_manager.dart';
 
 class KeyboardManagerWidget extends StatefulWidget {
-
   /// The widget behind the view where the drag to close is enabled
   final Widget child;
 
-  final Function onKeyboardOpen;
-  final Function onKeyboardClose;
-  
-  KeyboardManagerWidget(
-      {Key key, @required this.child, this.onKeyboardOpen, this.onKeyboardClose})
-      : super(key: key);
+  final Function? onKeyboardOpen;
+  final Function? onKeyboardClose;
+
+  KeyboardManagerWidget({
+    Key? key,
+    required this.child,
+    this.onKeyboardOpen,
+    this.onKeyboardClose,
+  }) : super(key: key);
 
   KeyboardManagerWidgetState createState() => KeyboardManagerWidgetState();
 }
 
 class KeyboardManagerWidgetState extends State<KeyboardManagerWidget> {
-  ChannelReceiver _channelReceiver;
+  /// Only initialised on IOS
+  late ChannelReceiver _channelReceiver;
 
   List<int> _pointers = [];
-  int get activePointer => _pointers.length > 0 ? _pointers.first : null;
+  int? get activePointer => _pointers.length > 0 ? _pointers.first : null;
 
   List<double> _velocities = [];
   double _velocity = 0.0;
@@ -57,21 +60,19 @@ class KeyboardManagerWidgetState extends State<KeyboardManagerWidget> {
   Widget build(BuildContext context) {
     var bottom = MediaQuery.of(context).viewInsets.bottom;
     var keyboardOpen = bottom > 0;
-    var oldKeyboardOpen = _keyboardOpen ?? !keyboardOpen;
+    var oldKeyboardOpen = _keyboardOpen;
     _keyboardOpen = keyboardOpen;
-    
+
     if (_keyboardOpen) {
       dismissed = false;
       _keyboardHeight = bottom;
-      if(!oldKeyboardOpen && activePointer == null) {
-        if(widget.onKeyboardOpen != null)
-          widget.onKeyboardOpen();
+      if (!oldKeyboardOpen && activePointer == null) {
+        widget.onKeyboardOpen?.call();
       }
     } else {
       // Close notification if the keyobard closes while not dragging
-      if(oldKeyboardOpen && activePointer == null) {
-        if(widget.onKeyboardClose != null)
-          widget.onKeyboardClose();
+      if (oldKeyboardOpen && activePointer == null) {
+        widget.onKeyboardClose?.call();
         dismissed = true;
       }
     }
@@ -109,8 +110,7 @@ class KeyboardManagerWidgetState extends State<KeyboardManagerWidget> {
                   } else {
                     _dismissing = false;
                     dismissed = true;
-                    if(widget.onKeyboardClose != null)
-                      widget.onKeyboardClose();
+                    widget.onKeyboardClose?.call();
                   }
                 });
               } else {
@@ -124,10 +124,9 @@ class KeyboardManagerWidgetState extends State<KeyboardManagerWidget> {
           }
 
           if (!Platform.isIOS) {
-            if (!_keyboardOpen){
+            if (!_keyboardOpen) {
               dismissed = true;
-              if(widget.onKeyboardClose != null)
-                widget.onKeyboardClose();
+              widget.onKeyboardClose?.call();
             }
           }
         }
@@ -150,10 +149,9 @@ class KeyboardManagerWidgetState extends State<KeyboardManagerWidget> {
                   hideKeyboard(true);
                 }
               } else if (_velocity < -0.5) {
-                if (!_keyboardOpen){
+                if (!_keyboardOpen) {
                   showKeyboard(true);
-                  if(widget.onKeyboardOpen != null)
-                    widget.onKeyboardOpen();
+                  widget.onKeyboardClose?.call();
                 }
               }
             }
@@ -164,10 +162,9 @@ class KeyboardManagerWidgetState extends State<KeyboardManagerWidget> {
                 showKeyboard(false);
               }
             } else {
-              if (!_keyboardOpen){
+              if (!_keyboardOpen) {
                 showKeyboard(true);
-                if(widget.onKeyboardOpen != null)
-                  widget.onKeyboardOpen();
+                widget.onKeyboardOpen?.call();
               }
             }
           }
@@ -213,12 +210,12 @@ class KeyboardManagerWidgetState extends State<KeyboardManagerWidget> {
     SystemChannels.textInput.invokeMethod('TextInput.hide');
     FocusScope.of(context).requestFocus(FocusNode());
   }
-  
-  Future<void> removeImageKeyboard()async{
+
+  Future<void> removeImageKeyboard() async {
     ChannelManager.updateScroll(_keyboardHeight);
   }
 
-  Future<void> safeHideKeyboard()async {
+  Future<void> safeHideKeyboard() async {
     await removeImageKeyboard();
     _hideKeyboard();
   }
diff --git a/pubspec.lock b/pubspec.lock
index aebdafa..49a0ce6 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -7,28 +7,49 @@ packages:
       name: async
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.3.0"
+    version: "2.5.0"
   boolean_selector:
     dependency: transitive
     description:
       name: boolean_selector
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.0.5"
+    version: "2.1.0"
+  characters:
+    dependency: transitive
+    description:
+      name: characters
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.0"
   charcode:
     dependency: transitive
     description:
       name: charcode
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.2"
+    version: "1.2.0"
+  clock:
+    dependency: transitive
+    description:
+      name: clock
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.0"
   collection:
     dependency: transitive
     description:
       name: collection
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.14.11"
+    version: "1.15.0"
+  fake_async:
+    dependency: transitive
+    description:
+      name: fake_async
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.2.0"
   flutter:
     dependency: "direct main"
     description: flutter
@@ -45,35 +66,21 @@ packages:
       name: matcher
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.12.5"
+    version: "0.12.10"
   meta:
     dependency: transitive
     description:
       name: meta
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.7"
+    version: "1.3.0"
   path:
     dependency: transitive
     description:
       name: path
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.6.4"
-  pedantic:
-    dependency: transitive
-    description:
-      name: pedantic
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "1.8.0+1"
-  quiver:
-    dependency: transitive
-    description:
-      name: quiver
-      url: "https://pub.dartlang.org"
-    source: hosted
-    version: "2.0.5"
+    version: "1.8.0"
   sky_engine:
     dependency: transitive
     description: flutter
@@ -85,55 +92,55 @@ packages:
       name: source_span
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.5.5"
+    version: "1.8.0"
   stack_trace:
     dependency: transitive
     description:
       name: stack_trace
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.9.3"
+    version: "1.10.0"
   stream_channel:
     dependency: transitive
     description:
       name: stream_channel
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.0.0"
+    version: "2.1.0"
   string_scanner:
     dependency: transitive
     description:
       name: string_scanner
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.0.5"
+    version: "1.1.0"
   term_glyph:
     dependency: transitive
     description:
       name: term_glyph
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.0"
+    version: "1.2.0"
   test_api:
     dependency: transitive
     description:
       name: test_api
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "0.2.5"
+    version: "0.2.19"
   typed_data:
     dependency: transitive
     description:
       name: typed_data
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "1.1.6"
+    version: "1.3.0"
   vector_math:
     dependency: transitive
     description:
       name: vector_math
       url: "https://pub.dartlang.org"
     source: hosted
-    version: "2.0.8"
+    version: "2.1.0"
 sdks:
-  dart: ">=2.2.2 <3.0.0"
+  dart: ">=2.12.0 <3.0.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index b16f1d8..e12b921 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,11 +1,11 @@
 name: flutter_interactive_keyboard
 description: A flutter plugin to dismiss the keyboard interactively similar to the IOS native behavior. On Android the functionality is mimed without drag.
-version: 0.1.3
+version: 0.2.0
 author: Mattia Crovero <mcrovero@gmail.com>
 homepage: https://github.com/mcrovero/flutter_interactive_keyboard
 
 environment:
-  sdk: ">=2.1.0 <3.0.0"
+  sdk: '>=2.12.0 <3.0.0'
 
 dependencies:
   flutter: