build: Android's built-in Kotlin, the three plugins applying KGP themselves patched in third_party/
AGP 9 compiles Kotlin itself (android.builtInKotlin=true in every app), and warns that applying the Kotlin Gradle Plugin will soon fail. flutter_web_auth_2 5.1.0, keyboard_height_plugin 0.3.0 and flutter_tts 4.2.5 still apply it unconditionally, so their pub releases are copied into third_party/ with only their android/build.gradle changed, and the root overrides them by path (third_party/README.md says when to drop each). The servers' images copy third_party/, as pub refuses an override whose path is missing. third_party/ isn't our own code: left out of the analysis and the format check. All four apps' APKs build without the warning. A Kotlin daemon's session file that slipped into Train's android/ goes, and every app's android/.gitignore keeps .kotlin/ out. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
396e010949
commit
438ce20dbf
15 changed files with 8440 additions and 23 deletions
67
third_party/keyboard_height_plugin/CHANGELOG.md
vendored
Normal file
67
third_party/keyboard_height_plugin/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
## 0.3.0
|
||||
|
||||
### iOS Updates
|
||||
* Add Swift Package Manager support (fixes #17)
|
||||
* Flutter 3.44+ will default to SwiftPM; CocoaPods support is retained for backward compatibility
|
||||
* Added `Package.swift` manifest at `ios/keyboard_height_plugin/`
|
||||
* Source files are symlinked so both CocoaPods and SwiftPM resolve the same code
|
||||
|
||||
## 0.2.0
|
||||
|
||||
**BREAKING CHANGES:**
|
||||
This version requires modern Android build tooling. For projects using older versions, please continue using version 0.1.5.
|
||||
|
||||
### Requirements
|
||||
- Android Gradle Plugin 8.6.0+
|
||||
- Gradle 8.7+
|
||||
- Kotlin 2.1.0+
|
||||
- Java 17+
|
||||
|
||||
### Android Updates
|
||||
* **BREAKING:** Update compileSdkVersion from 31 to 34 (fixes #14)
|
||||
* **BREAKING:** Update Android Gradle Plugin from 7.2.0 to 8.6.0
|
||||
* **BREAKING:** Update Kotlin from 1.7.10 to 2.1.0
|
||||
* **BREAKING:** Migrate to declarative Gradle plugin system (Gradle 8.x requirement)
|
||||
* Add namespace declaration for AGP 8.6+ compatibility
|
||||
* minSdkVersion remains 16 (Android 4.1+) - no change to device compatibility
|
||||
|
||||
### iOS Updates
|
||||
* Add Privacy Manifest (PrivacyInfo.xcprivacy) required for App Store submissions (fixes #6)
|
||||
* Fix example app Podfile configuration to eliminate RunnerTests errors
|
||||
|
||||
### Infrastructure
|
||||
* Add comprehensive CI/CD pipeline with GitHub Actions
|
||||
* Add automated testing for code analysis, formatting, and builds
|
||||
* Add PR template with testing checklist
|
||||
* Add TESTING.md documentation
|
||||
* Update example app .gitignore for Flutter-generated files
|
||||
|
||||
### Migration Guide
|
||||
If you need to upgrade from 0.1.5:
|
||||
1. Update your project to use AGP 8.6+, Gradle 8.7+, Kotlin 2.1+, and Java 17+
|
||||
2. Follow the Flutter AGP migration guide: https://docs.flutter.dev/release/breaking-changes/flutter-gradle-plugin-apply
|
||||
|
||||
If your project cannot upgrade these dependencies yet, remain on version 0.1.5.
|
||||
|
||||
## 0.0.1
|
||||
|
||||
* Initial release.
|
||||
|
||||
## 0.0.2
|
||||
|
||||
* Documentation.
|
||||
|
||||
## 0.0.3
|
||||
|
||||
* More documentation.
|
||||
|
||||
## 0.0.4
|
||||
|
||||
* N/A
|
||||
|
||||
## 0.0.5
|
||||
|
||||
* Support for AGP 8.0.0
|
||||
|
||||
## 0.1.5
|
||||
* Merge in fix for incorrect height when navigation bar is not visible. https://github.com/nschairer/keyboard_height_plugin/pull/8/files
|
||||
29
third_party/keyboard_height_plugin/LICENSE
vendored
Normal file
29
third_party/keyboard_height_plugin/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2023, Noah Schairer
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
85
third_party/keyboard_height_plugin/README.md
vendored
Normal file
85
third_party/keyboard_height_plugin/README.md
vendored
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
# Keyboard Height Plugin for Flutter
|
||||
|
||||
`keyboard_height_plugin` is a Flutter plugin for iOS and Android that provides the keyboard size before the keyboard animation occurs for showing or hiding it. This helps eliminate lag when positioning widgets around the keyboard, such as placing a TextField above the keyboard.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Version 0.3.0+ (Current)
|
||||
- **Android:**
|
||||
- Android Gradle Plugin (AGP) 8.6.0+
|
||||
- Gradle 8.7+
|
||||
- Kotlin 2.1.0+
|
||||
- Java 17+
|
||||
- minSdkVersion 16 (Android 4.1+)
|
||||
- compileSdkVersion 34+
|
||||
- **iOS:**
|
||||
- iOS 12.0+
|
||||
- Supports both CocoaPods and Swift Package Manager
|
||||
- Includes Privacy Manifest for App Store compliance
|
||||
|
||||
### Version 0.1.5 (Legacy Support)
|
||||
For projects that cannot upgrade to the modern build tools, use version 0.1.5:
|
||||
- Android Gradle Plugin 7.x
|
||||
- Kotlin 1.7.x
|
||||
- Java 11+
|
||||
|
||||
## Installation
|
||||
|
||||
To install `keyboard_height_plugin`, add it to your `pubspec.yaml` file under the `dependencies` section:
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
keyboard_height_plugin: ^0.3.0
|
||||
```
|
||||
|
||||
**For legacy projects:**
|
||||
```yaml
|
||||
dependencies:
|
||||
keyboard_height_plugin: 0.1.5
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
To use the `keyboard_height_plugin`, first import it in your Dart file:
|
||||
|
||||
```dart
|
||||
import 'package:keyboard_height_plugin/keyboard_height_plugin.dart';
|
||||
```
|
||||
|
||||
Next, create a stateful widget and declare a variable to store the keyboard height and create an instance of the `KeyboardHeightPlugin`:
|
||||
|
||||
```dart
|
||||
class _HomePageState extends State<HomePage>; {
|
||||
double _keyboardHeight = 0;
|
||||
final KeyboardHeightPlugin _keyboardHeightPlugin = KeyboardHeightPlugin();
|
||||
// ... rest of code ...
|
||||
}
|
||||
```
|
||||
|
||||
Then, initialize the `KeyboardHeightPlugin` in your `initState` method and listen for changes in the keyboard height:
|
||||
|
||||
```dart
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_keyboardHeightPlugin.onKeyboardHeightChanged((double height) {
|
||||
setState(() {
|
||||
_keyboardHeight = height;
|
||||
});
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
Use the `_keyboardHeight` variable to position your widgets around the keyboard.
|
||||
|
||||
## Example
|
||||
|
||||
For a complete example on how to use the `keyboard_height_plugin`, please refer to the [`example`](example) directory in the repository.
|
||||
|
||||
## Contributing
|
||||
|
||||
If you encounter any issues or have suggestions for improvements, feel free to open an issue or submit a pull request on the project's GitHub repository.
|
||||
|
||||
## License
|
||||
|
||||
This plugin is licensed under the [BSD 3-Clause License](LICENSE).
|
||||
53
third_party/keyboard_height_plugin/android/build.gradle
vendored
Normal file
53
third_party/keyboard_height_plugin/android/build.gradle
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
group 'com.nschairer.keyboard_height_plugin'
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '2.1.0'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.6.0'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 34
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
}
|
||||
if (project.android.hasProperty("namespace")) {
|
||||
namespace 'com.nschairer.keyboard_height_plugin'
|
||||
}
|
||||
}
|
||||
|
||||
// Halkyon's patch (4 Nov 2026): Kotlin built into the Android Gradle plugin
|
||||
// (AGP 9, android.builtInKotlin=true) rather than the Kotlin Gradle plugin
|
||||
// applied here, as Flutter's guide for plugin authors has it.
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_1_8
|
||||
}
|
||||
}
|
||||
1
third_party/keyboard_height_plugin/android/settings.gradle
vendored
Normal file
1
third_party/keyboard_height_plugin/android/settings.gradle
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
rootProject.name = 'keyboard_height_plugin'
|
||||
3
third_party/keyboard_height_plugin/android/src/main/AndroidManifest.xml
vendored
Normal file
3
third_party/keyboard_height_plugin/android/src/main/AndroidManifest.xml
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.nschairer.keyboard_height_plugin">
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
package com.nschairer.keyboard_height_plugin
|
||||
import android.graphics.Rect
|
||||
import android.os.Build
|
||||
import androidx.annotation.NonNull
|
||||
import android.view.ViewTreeObserver
|
||||
import androidx.annotation.RequiresApi
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||
import io.flutter.plugin.common.EventChannel
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
|
||||
|
||||
class KeyboardHeightPlugin : FlutterPlugin, EventChannel.StreamHandler, ActivityAware {
|
||||
private val keyboardHeightEventChannelName = "keyboardHeightEventChannel"
|
||||
private var eventSink: EventChannel.EventSink? = null
|
||||
private var eventChannel: EventChannel? = null
|
||||
private var activityPluginBinding: ActivityPluginBinding? = null
|
||||
|
||||
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
eventChannel = EventChannel(flutterPluginBinding.binaryMessenger, keyboardHeightEventChannelName)
|
||||
eventChannel?.setStreamHandler(this)
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
eventChannel?.setStreamHandler(null)
|
||||
}
|
||||
|
||||
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
|
||||
eventSink = events
|
||||
val rootView = activityPluginBinding?.activity?.window?.decorView?.rootView
|
||||
rootView?.viewTreeObserver?.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
|
||||
override fun onGlobalLayout() {
|
||||
val r = Rect()
|
||||
rootView.getWindowVisibleDisplayFrame(r)
|
||||
|
||||
val screenHeight = rootView.height
|
||||
val navigationBarHeight = getNavigationBarHeight();
|
||||
var keypadHeight = screenHeight - r.bottom
|
||||
if (isNavigationBarVisible()) {
|
||||
keypadHeight -= navigationBarHeight
|
||||
}
|
||||
val displayMetrics = activityPluginBinding?.activity?.resources?.displayMetrics
|
||||
val logicalKeypadHeight = keypadHeight / (displayMetrics?.density ?: 1f)
|
||||
|
||||
if (keypadHeight > screenHeight * 0.15) {
|
||||
events?.success(logicalKeypadHeight.toDouble())
|
||||
} else {
|
||||
events?.success(0.0)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onCancel(arguments: Any?) {
|
||||
eventSink = null
|
||||
}
|
||||
|
||||
private fun getNavigationBarHeight(): Int {
|
||||
val resourceId = activityPluginBinding?.activity?.resources?.getIdentifier("navigation_bar_height", "dimen", "android")
|
||||
return if (resourceId != null && resourceId > 0) {
|
||||
activityPluginBinding?.activity?.resources?.getDimensionPixelSize(resourceId) ?: 0
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
private fun isNavigationBarVisible(): Boolean {
|
||||
val decorView = activityPluginBinding?.activity?.window?.decorView
|
||||
val rootWindowInsets = decorView?.rootWindowInsets ?: return false
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
rootWindowInsets.isVisible(android.view.WindowInsets.Type.navigationBars())
|
||||
} else {
|
||||
val systemWindowInsetBottom = rootWindowInsets.systemWindowInsetBottom
|
||||
systemWindowInsetBottom > 0
|
||||
}
|
||||
}
|
||||
|
||||
// Implement ActivityAware methods
|
||||
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
|
||||
activityPluginBinding = binding
|
||||
}
|
||||
|
||||
override fun onDetachedFromActivityForConfigChanges() {
|
||||
activityPluginBinding = null
|
||||
}
|
||||
|
||||
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
|
||||
activityPluginBinding = binding
|
||||
}
|
||||
|
||||
override fun onDetachedFromActivity() {
|
||||
activityPluginBinding = null
|
||||
}
|
||||
}
|
||||
47
third_party/keyboard_height_plugin/ios/Classes/KeyboardHeightPlugin.swift
vendored
Normal file
47
third_party/keyboard_height_plugin/ios/Classes/KeyboardHeightPlugin.swift
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import Flutter
|
||||
import UIKit
|
||||
|
||||
public class KeyboardHeightPlugin: NSObject, FlutterPlugin, FlutterStreamHandler {
|
||||
private var eventSink: FlutterEventSink?
|
||||
private var eventChannel: FlutterEventChannel?
|
||||
|
||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||
let instance = KeyboardHeightPlugin()
|
||||
instance.eventChannel = FlutterEventChannel(name: "keyboardHeightEventChannel", binaryMessenger: registrar.messenger())
|
||||
instance.eventChannel?.setStreamHandler(instance)
|
||||
}
|
||||
|
||||
public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
|
||||
eventSink = events
|
||||
registerKeyboardObservers()
|
||||
return nil
|
||||
}
|
||||
|
||||
public func onCancel(withArguments arguments: Any?) -> FlutterError? {
|
||||
eventSink = nil
|
||||
unregisterKeyboardObservers()
|
||||
return nil
|
||||
}
|
||||
|
||||
private func registerKeyboardObservers() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
|
||||
}
|
||||
|
||||
private func unregisterKeyboardObservers() {
|
||||
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
|
||||
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
|
||||
}
|
||||
|
||||
@objc private func keyboardWillShow(notification: NSNotification) {
|
||||
if let userInfo = notification.userInfo,
|
||||
let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect {
|
||||
eventSink?(NSNumber(value: keyboardFrame.height))
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func keyboardWillHide(notification: NSNotification) {
|
||||
eventSink?(NSNumber(value: 0.0))
|
||||
}
|
||||
}
|
||||
|
||||
23
third_party/keyboard_height_plugin/ios/PrivacyInfo.xcprivacy
vendored
Normal file
23
third_party/keyboard_height_plugin/ios/PrivacyInfo.xcprivacy
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
<key>NSPrivacyTrackingDomains</key>
|
||||
<array/>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>CA92.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
24
third_party/keyboard_height_plugin/ios/keyboard_height_plugin.podspec
vendored
Normal file
24
third_party/keyboard_height_plugin/ios/keyboard_height_plugin.podspec
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#
|
||||
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
|
||||
# Run `pod lib lint keyboard_height_plugin.podspec` to validate before publishing.
|
||||
#
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'keyboard_height_plugin'
|
||||
s.version = '0.0.1'
|
||||
s.summary = 'A new Flutter plugin project.'
|
||||
s.description = <<-DESC
|
||||
A new Flutter plugin project.
|
||||
DESC
|
||||
s.homepage = 'http://example.com'
|
||||
s.license = { :file => '../LICENSE' }
|
||||
s.author = { 'Your Company' => 'email@example.com' }
|
||||
s.source = { :path => '.' }
|
||||
s.source_files = 'Classes/**/*'
|
||||
s.resource_bundles = {'keyboard_height_plugin_privacy' => ['PrivacyInfo.xcprivacy']}
|
||||
s.dependency 'Flutter'
|
||||
s.platform = :ios, '12.0'
|
||||
|
||||
# Flutter.framework does not contain a i386 slice.
|
||||
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
|
||||
s.swift_version = '5.0'
|
||||
end
|
||||
23
third_party/keyboard_height_plugin/ios/keyboard_height_plugin/Package.swift
vendored
Normal file
23
third_party/keyboard_height_plugin/ios/keyboard_height_plugin/Package.swift
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// swift-tools-version: 5.9
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "keyboard_height_plugin",
|
||||
platforms: [
|
||||
.iOS(.v12)
|
||||
],
|
||||
products: [
|
||||
.library(name: "keyboard-height-plugin", targets: ["keyboard_height_plugin"])
|
||||
],
|
||||
dependencies: [],
|
||||
targets: [
|
||||
.target(
|
||||
name: "keyboard_height_plugin",
|
||||
resources: [
|
||||
.process("PrivacyInfo.xcprivacy")
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
import Flutter
|
||||
import UIKit
|
||||
|
||||
public class KeyboardHeightPlugin: NSObject, FlutterPlugin, FlutterStreamHandler {
|
||||
private var eventSink: FlutterEventSink?
|
||||
private var eventChannel: FlutterEventChannel?
|
||||
|
||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||
let instance = KeyboardHeightPlugin()
|
||||
instance.eventChannel = FlutterEventChannel(name: "keyboardHeightEventChannel", binaryMessenger: registrar.messenger())
|
||||
instance.eventChannel?.setStreamHandler(instance)
|
||||
}
|
||||
|
||||
public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
|
||||
eventSink = events
|
||||
registerKeyboardObservers()
|
||||
return nil
|
||||
}
|
||||
|
||||
public func onCancel(withArguments arguments: Any?) -> FlutterError? {
|
||||
eventSink = nil
|
||||
unregisterKeyboardObservers()
|
||||
return nil
|
||||
}
|
||||
|
||||
private func registerKeyboardObservers() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
|
||||
}
|
||||
|
||||
private func unregisterKeyboardObservers() {
|
||||
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
|
||||
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
|
||||
}
|
||||
|
||||
@objc private func keyboardWillShow(notification: NSNotification) {
|
||||
if let userInfo = notification.userInfo,
|
||||
let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect {
|
||||
eventSink?(NSNumber(value: keyboardFrame.height))
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func keyboardWillHide(notification: NSNotification) {
|
||||
eventSink?(NSNumber(value: 0.0))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
<key>NSPrivacyTrackingDomains</key>
|
||||
<array/>
|
||||
<key>NSPrivacyCollectedDataTypes</key>
|
||||
<array/>
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>CA92.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
29
third_party/keyboard_height_plugin/lib/keyboard_height_plugin.dart
vendored
Normal file
29
third_party/keyboard_height_plugin/lib/keyboard_height_plugin.dart
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import 'dart:async';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
typedef KeyboardHeightCallback = void Function(double height);
|
||||
|
||||
class KeyboardHeightPlugin {
|
||||
static const EventChannel _keyboardHeightEventChannel =
|
||||
EventChannel('keyboardHeightEventChannel');
|
||||
|
||||
StreamSubscription? _keyboardHeightSubscription;
|
||||
|
||||
void onKeyboardHeightChanged(KeyboardHeightCallback callback) {
|
||||
if (_keyboardHeightSubscription != null) {
|
||||
_keyboardHeightSubscription!.cancel();
|
||||
}
|
||||
_keyboardHeightSubscription =
|
||||
_keyboardHeightEventChannel.receiveBroadcastStream().listen(
|
||||
(dynamic height) {
|
||||
callback(height as double);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
if (_keyboardHeightSubscription != null) {
|
||||
_keyboardHeightSubscription!.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
72
third_party/keyboard_height_plugin/pubspec.yaml
vendored
Normal file
72
third_party/keyboard_height_plugin/pubspec.yaml
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
name: keyboard_height_plugin
|
||||
description: Flutter plugin that emits keyboard height before it shows (ios/android)
|
||||
version: 0.3.0
|
||||
repository: https://github.com/nschairer/keyboard_height_plugin
|
||||
|
||||
environment:
|
||||
sdk: '>=2.19.6 <4.0.0'
|
||||
flutter: ">=2.5.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
plugin_platform_interface: ^2.0.2
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^2.0.0
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
# The following section is specific to Flutter packages.
|
||||
flutter:
|
||||
# This section identifies this Flutter project as a plugin project.
|
||||
# The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
|
||||
# which should be registered in the plugin registry. This is required for
|
||||
# using method channels.
|
||||
# The Android 'package' specifies package in which the registered class is.
|
||||
# This is required for using method channels on Android.
|
||||
# The 'ffiPlugin' specifies that native code should be built and bundled.
|
||||
# This is required for using `dart:ffi`.
|
||||
# All these are used by the tooling to maintain consistency when
|
||||
# adding or updating assets for this project.
|
||||
plugin:
|
||||
platforms:
|
||||
android:
|
||||
package: com.nschairer.keyboard_height_plugin
|
||||
pluginClass: KeyboardHeightPlugin
|
||||
ios:
|
||||
pluginClass: KeyboardHeightPlugin
|
||||
|
||||
# To add assets to your plugin package, add an assets section, like this:
|
||||
# assets:
|
||||
# - images/a_dot_burr.jpeg
|
||||
# - images/a_dot_ham.jpeg
|
||||
#
|
||||
# For details regarding assets in packages, see
|
||||
# https://flutter.dev/assets-and-images/#from-packages
|
||||
#
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware
|
||||
|
||||
# To add custom fonts to your plugin package, add a fonts section here,
|
||||
# in this "flutter" section. Each entry in this list should have a
|
||||
# "family" key with the font family name, and a "fonts" key with a
|
||||
# list giving the asset and other descriptors for the font. For
|
||||
# example:
|
||||
# fonts:
|
||||
# - family: Schyler
|
||||
# fonts:
|
||||
# - asset: fonts/Schyler-Regular.ttf
|
||||
# - asset: fonts/Schyler-Italic.ttf
|
||||
# style: italic
|
||||
# - family: Trajan Pro
|
||||
# fonts:
|
||||
# - asset: fonts/TrajanPro.ttf
|
||||
# - asset: fonts/TrajanPro_Bold.ttf
|
||||
# weight: 700
|
||||
#
|
||||
# For details regarding fonts in packages, see
|
||||
# https://flutter.dev/custom-fonts/#from-packages
|
||||
Loading…
Reference in a new issue