Browse Source

[infra_ui][keyboard] Impl android support for keyboard

Jaylen Bian 3 years ago
parent
commit
915975d522

+ 2 - 3
app_flowy/packages/flowy_infra_ui/android/build.gradle

@@ -28,8 +28,7 @@ android {
         sourceCompatibility JavaVersion.VERSION_1_8
         targetCompatibility JavaVersion.VERSION_1_8
     }
-
-    defaultConfig {
-        minSdkVersion 16
+    dependencies {
+        implementation "androidx.core:core:1.5.0-rc01"
     }
 }

+ 57 - 14
app_flowy/packages/flowy_infra_ui/android/src/main/java/com/example/flowy_infra_ui/FlowyInfraUiPlugin.java

@@ -1,38 +1,81 @@
 package com.example.flowy_infra_ui;
 
+import android.app.Activity;
+
 import androidx.annotation.NonNull;
 
+import com.example.flowy_infra_ui.event.KeyboardEventHandler;
+
 import io.flutter.embedding.engine.plugins.FlutterPlugin;
+import io.flutter.embedding.engine.plugins.activity.ActivityAware;
+import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
+import io.flutter.plugin.common.EventChannel;
 import io.flutter.plugin.common.MethodCall;
 import io.flutter.plugin.common.MethodChannel;
 import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
 import io.flutter.plugin.common.MethodChannel.Result;
 
 /** FlowyInfraUiPlugin */
-public class FlowyInfraUiPlugin implements FlutterPlugin, MethodCallHandler {
-  /// The MethodChannel that will the communication between Flutter and native Android
-  ///
-  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
-  /// when the Flutter Engine is detached from the Activity
-  private MethodChannel channel;
+public class FlowyInfraUiPlugin implements FlutterPlugin, ActivityAware, MethodCallHandler {
+
+  // MARK: - Constant
+  public static final String INFRA_UI_METHOD_CHANNEL_NAME = "flowy_infra_ui_method";
+  public static final String INFRA_UI_KEYBOARD_EVENT_CHANNEL_NAME = "flowy_infra_ui_event/keyboard";
+
+  public static final String INFRA_UI_METHOD_GET_PLATFORM_VERSION = "getPlatformVersion";
+
+  // Method Channel
+  private MethodChannel methodChannel;
+  // Event Channel
+  private KeyboardEventHandler keyboardEventHandler = new KeyboardEventHandler();
 
   @Override
   public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
-    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "flowy_infra_ui");
-    channel.setMethodCallHandler(this);
+    methodChannel = new MethodChannel(
+            flutterPluginBinding.getBinaryMessenger(),
+            INFRA_UI_METHOD_CHANNEL_NAME);
+    methodChannel.setMethodCallHandler(this);
+
+    final EventChannel keyboardEventChannel = new EventChannel(
+            flutterPluginBinding.getBinaryMessenger(),
+            INFRA_UI_KEYBOARD_EVENT_CHANNEL_NAME);
+    keyboardEventChannel.setStreamHandler(keyboardEventHandler);
+  }
+
+  @Override
+  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
+    methodChannel.setMethodCallHandler(null);
+    keyboardEventHandler.cancelObserveKeyboardAction();
   }
 
+  @Override
+  public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
+    keyboardEventHandler.observeKeyboardAction(binding.getActivity());
+  }
+
+  @Override
+  public void onDetachedFromActivityForConfigChanges() {
+    keyboardEventHandler.cancelObserveKeyboardAction();
+  }
+
+  @Override
+  public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
+    keyboardEventHandler.observeKeyboardAction(binding.getActivity());
+  }
+
+  @Override
+  public void onDetachedFromActivity() {
+    keyboardEventHandler.cancelObserveKeyboardAction();
+  }
+
+  // MARK: - Method Channel
+
   @Override
   public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
-    if (call.method.equals("getPlatformVersion")) {
+    if (call.method.equals(INFRA_UI_METHOD_GET_PLATFORM_VERSION)) {
       result.success("Android " + android.os.Build.VERSION.RELEASE);
     } else {
       result.notImplemented();
     }
   }
-
-  @Override
-  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
-    channel.setMethodCallHandler(null);
-  }
 }

+ 53 - 0
app_flowy/packages/flowy_infra_ui/android/src/main/java/com/example/flowy_infra_ui/event/KeyboardEventHandler.java

@@ -0,0 +1,53 @@
+package com.example.flowy_infra_ui.event;
+
+import android.app.Activity;
+import android.os.Build;
+import android.view.View;
+
+import androidx.annotation.RequiresApi;
+import androidx.core.view.OnApplyWindowInsetsListener;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+
+import io.flutter.plugin.common.EventChannel;
+
+public class KeyboardEventHandler implements EventChannel.StreamHandler {
+    private EventChannel.EventSink eventSink;
+    private View rootView;
+    private boolean isKeyboardShow = false;
+
+    @Override
+    public void onListen(Object arguments, EventChannel.EventSink events) {
+        eventSink = events;
+    }
+
+    @Override
+    public void onCancel(Object arguments) {
+        eventSink = null;
+    }
+
+    // MARK: - Helper
+
+    @RequiresApi(Build.VERSION_CODES.R)
+    public void observeKeyboardAction(Activity activity) {
+        rootView = activity.findViewById(android.R.id.content);
+
+        ViewCompat.setOnApplyWindowInsetsListener(rootView, new OnApplyWindowInsetsListener() {
+            @Override
+            public WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat insets) {
+                isKeyboardShow = insets.isVisible(WindowInsetsCompat.Type.ime());
+                if (eventSink != null) {
+                    eventSink.success(isKeyboardShow);
+                }
+                return insets;
+            }
+        });
+    }
+
+    public void cancelObserveKeyboardAction() {
+        if (rootView != null) {
+            ViewCompat.setOnApplyWindowInsetsListener(rootView, null);
+            rootView = null;
+        }
+    }
+}

+ 1 - 1
app_flowy/packages/flowy_infra_ui/example/android/app/build.gradle

@@ -26,7 +26,6 @@ apply plugin: 'kotlin-android'
 apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
 
 android {
-    compileSdkVersion 30
 
     compileOptions {
         sourceCompatibility JavaVersion.VERSION_1_8
@@ -57,6 +56,7 @@ android {
             signingConfig signingConfigs.debug
         }
     }
+    compileSdkVersion 30
 }
 
 flutter {

+ 1 - 0
app_flowy/packages/flowy_infra_ui/example/android/app/src/main/java/com/example/flowy_infra_ui_example/MainActivity.java

@@ -3,4 +3,5 @@ package com.example.flowy_infra_ui_example;
 import io.flutter.embedding.android.FlutterActivity;
 
 public class MainActivity extends FlutterActivity {
+
 }

+ 0 - 6
app_flowy/packages/flowy_infra_ui/example/android/app/src/main/kotlin/com/example/flowy_infra_ui_example/MainActivity.kt

@@ -1,6 +0,0 @@
-package com.example.flowy_infra_ui_example
-
-import io.flutter.embedding.android.FlutterActivity
-
-class MainActivity: FlutterActivity() {
-}

+ 1 - 1
app_flowy/packages/flowy_infra_ui/example/android/build.gradle

@@ -6,7 +6,7 @@ buildscript {
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle:4.1.0'
+        classpath 'com.android.tools.build:gradle:4.1.1'
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
     }
 }

+ 2 - 2
app_flowy/packages/flowy_infra_ui/example/android/gradle/wrapper/gradle-wrapper.properties

@@ -1,6 +1,6 @@
-#Fri Jun 23 08:50:38 CEST 2017
+#Sat Jul 17 23:27:26 CST 2021
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip

+ 5 - 1
app_flowy/packages/flowy_infra_ui/ios/Classes/SwiftFlowyInfraUiPlugin.swift

@@ -6,6 +6,8 @@ public class SwiftFlowyInfraUiPlugin: NSObject, FlutterPlugin {
     enum Constant {
         static let infraUIMethodChannelName = "flowy_infra_ui_method"
         static let infraUIKeyboardEventChannelName = "flowy_infra_ui_event/keyboard"
+
+        static let infraUIMethodGetPlatformVersion = "getPlatformVersion"
     }
 
     public static func register(with registrar: FlutterPluginRegistrar) {
@@ -26,8 +28,10 @@ public class SwiftFlowyInfraUiPlugin: NSObject, FlutterPlugin {
 
     public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
         switch call.method {
+        case Constant.infraUIMethodGetPlatformVersion:
+            result("iOS " + UIDevice.current.systemVersion)
         default:
-            assertionFailure("Unsupported method \(call.method)")
+            result(FlutterMethodNotImplemented)
         }
     }