Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ jobs:
working-directory: ./flutter_keyboard_visibility
- run: flutter pub get
working-directory: ./flutter_keyboard_visibility/example
- run: flutter pub get
working-directory: ./flutter_keyboard_visibility/example_old
- run: flutter test --no-sound-null-safety --coverage
- run: flutter test --coverage
working-directory: ./flutter_keyboard_visibility
- uses: codecov/codecov-action@v1
- uses: codecov/codecov-action@v2
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./flutter_keyboard_visibility/coverage/lcov.info
Expand All @@ -47,8 +45,6 @@ jobs:
working-directory: ./flutter_keyboard_visibility
- run: flutter pub get
working-directory: ./flutter_keyboard_visibility/example
- run: flutter pub get
working-directory: ./flutter_keyboard_visibility/example_old
- run: flutter analyze
working-directory: ./flutter_keyboard_visibility_platform_interface
- run: flutter analyze
Expand All @@ -57,5 +53,3 @@ jobs:
working-directory: ./flutter_keyboard_visibility
- run: flutter analyze
working-directory: ./flutter_keyboard_visibility/example
- run: flutter analyze
working-directory: ./flutter_keyboard_visibility/example_old
6 changes: 0 additions & 6 deletions .idea/runConfigurations/demo_with_provider.xml

This file was deleted.

22 changes: 22 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
The MIT License

Copyright (c) 2022 Jason Rai
All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
82 changes: 71 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# Flutter Keyboard Visibility
[![pub package](https://img.shields.io/pub/v/flutter_keyboard_visibility.svg?label=flutter_keyboard_visibility&color=blue)](https://pub.dev/packages/flutter_keyboard_visibility)
![ci](https://github.com/MisterJimson/flutter_keyboard_visibility/actions/workflows/test.yml/badge.svg?branch=master)
[![codecov](https://codecov.io/gh/MisterJimson/flutter_keyboard_visibility/branch/master/graph/badge.svg)](https://codecov.io/gh/MisterJimson/flutter_keyboard_visibility)

React to keyboard visibility changes.

### Note about Flutter Web support
### Note about Flutter Web and Desktop support

Web support is an open issue [here](https://github.com/MisterJimson/flutter_keyboard_visibility/issues/10). Currently this library will just return `false` for keyboard visibility on web.
Web support is an open issue [here](https://github.com/MisterJimson/flutter_keyboard_visibility/issues/10), desktop support is an open issue [here](https://github.com/MisterJimson/flutter_keyboard_visibility/issues/124). Currently this library will just return `false` for keyboard visibility on web and desktop.

## Install
[Install the package](https://pub.dev/packages/flutter_keyboard_visibility/install)
Expand All @@ -20,11 +21,11 @@ import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
@override
Widget build(BuildContext context) {
return KeyboardVisibilityBuilder(
builder: (context, isKeyboardVisible) {
return Text(
'The keyboard is: ${isKeyboardVisible ? 'VISIBLE' : 'NOT VISIBLE'}',
);
}
builder: (context, isKeyboardVisible) {
return Text(
'The keyboard is: ${isKeyboardVisible ? 'VISIBLE' : 'NOT VISIBLE'}',
);
}
);
```
### Option 2: Within your `Widget` tree using a provider
Expand Down Expand Up @@ -59,6 +60,9 @@ Query and/or subscribe to keyboard visibility directly with the

```dart
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'dart:async';

late StreamSubscription<bool> keyboardSubscription;

@override
void initState() {
Expand All @@ -69,10 +73,16 @@ void initState() {
print('Keyboard visibility direct query: ${keyboardVisibilityController.isVisible}');

// Subscribe
keyboardVisibilityController.onChange.listen((bool visible) {
print('Keyboard visibility update. Is visible: ${visible}');
keyboardSubscription = keyboardVisibilityController.onChange.listen((bool visible) {
print('Keyboard visibility update. Is visible: $visible');
});
}

@override
void dispose() {
keyboardSubscription.cancel();
super.dispose();
}
```
## Usage: Dismiss keyboard on tap
Place a `KeyboardDismissOnTap` near the top of your `Widget` tree. When a user taps outside of the currently focused `Widget`, the `Widget` will drop focus and the keyboard will be dismissed.
Expand All @@ -87,12 +97,62 @@ Widget build(BuildContext context) {
);
}
```
By default `KeyboardDismissOnTap` will only dismiss taps not captured by other interactive `Widget`s, like buttons. If you would like to dismiss the keyboard for any tap, including taps on interactive `Widget`s, set `dismissOnCapturedTaps` to true.
```dart
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';

// Somewhere near the top of your tree...
@override
Widget build(BuildContext context) {
return KeyboardDismissOnTap(
dismissOnCapturedTaps: true,
child: MyDemoPage(),
);
}
```
The `IgnoreKeyboardDismiss` `Widget` can be used to further refine which taps do and do not dismiss the keyboard. Checkout the example app for more detail.
## Testing
Call `KeyboardVisibility.setVisibilityForTesting(value)` to set a custom value to use during `flutter test`
### Testing using mocks
`KeyboardVisibilityProvider` and `KeyboardVisibilityBuilder` accept a `controller` parameter that allow you to mock or replace the logic for reporting keyboard visibility updates.
```dart
@GenerateMocks([KeyboardVisibilityController])
void main() {
testWidgets('It reports true when the keyboard is visible', (WidgetTester tester) async {
// Pretend that the keyboard is visible.
var mockController = MockKeyboardVisibilityController();
when(mockController.onChange)
.thenAnswer((_) => Stream.fromIterable([true]));
when(mockController.isVisible).thenAnswer((_) => true);

// Build a Widget tree and query KeyboardVisibilityProvider
// for the visibility of the keyboard.
bool? isKeyboardVisible;

await tester.pumpWidget(
KeyboardVisibilityProvider(
controller: mockController,
child: Builder(
builder: (BuildContext context) {
isKeyboardVisible =
KeyboardVisibilityProvider.isKeyboardVisible(context);
return SizedBox();
},
),
),
);

// Verify that KeyboardVisibilityProvider reported that the
// keyboard is visible.
expect(isKeyboardVisible, true);
});
}
```
### Testing with a global override
Call `KeyboardVisibilityTesting.setVisibilityForTesting(false);` to set a custom value to use during `flutter test`. This is set globally and will override the standard logic of the native platform.
```dart
void main() {
testWidgets('My Test', (WidgetTester tester) async {
KeyboardVisibility.setVisibilityForTesting(true);
KeyboardVisibilityTesting.setVisibilityForTesting(true);
await tester.pumpWidget(MyApp());
});
}
Expand Down
18 changes: 18 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
codecov:
require_ci_to_pass: yes

coverage:
range: 55..100
round: down
precision: 2
status:
project:
default:
target: 70%
threshold: 5%
branches:
- master
patch: off

comment:
layout: 'reach, diff, files'
39 changes: 39 additions & 0 deletions flutter_keyboard_visibility/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,42 @@
## [6.0.0] - December 19, 2023
* 5.4.3 republished as a new major version. The Android Gradle changes were breaking for some users so 5.4.3 was unpublished. Using this version may require you to update your Android Gradle version.

## [5.4.3] - May 20, 2023
Thanks to fabricio-godoi for reporting this issue.

* Fixed compatibility with Gradle 7 Android projects (support for Gradle 8 remains in place)

## [5.4.2] - May 11, 2023
Thanks to davidmartos96 for help with this release

* Add compatibility with AGP 8 (Android Gradle Plugin).
* Removed implicit-casts lint warning as it's no longer supported

## [5.4.1] - March 26, 2023

* Fixed `NSLocationWhenInUseUsageDescription` warning on iOS

## [5.4.0] - October 4, 2022
Thanks to cbenhagen for this feature

* Add endorsed stubs for Linux, macOS, and Windows.

## [5.3.0] - June 13, 2022

* Updated testing docs and made minor changes to allow to easier testing. See readme for details.

## [5.2.0] - February 15, 2022
Thanks to Andrflor for help with this feature release

* Added `dismissOnCapturedTaps` option to KeyboardDismissOnTap
* Added `IgnoreKeyboardDismiss` Widget

## [5.1.1] - January 13, 2022
Thanks to jpeiffer for this fix

* Updated Android tooling versions
* Replaced jcenter with mavenCentral

## [5.1.0] - October 15, 2021

* Removed Android v1 Embedding Support. If you created your Android project before Flutter 1.12 you
Expand Down
2 changes: 1 addition & 1 deletion flutter_keyboard_visibility/LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License

Copyright (c) 2006-2018
Copyright (c) 2022 Jason Rai
All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down
68 changes: 61 additions & 7 deletions flutter_keyboard_visibility/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

React to keyboard visibility changes.

### Note about Flutter Web support

Web support is an open issue [here](https://github.com/MisterJimson/flutter_keyboard_visibility/issues/10). Currently this library will just return `false` for keyboard visibility on web.

## Install
[Install the package](https://pub.dev/packages/flutter_keyboard_visibility/install)
## Usage: React to Keyboard Visibility Changes
Expand All @@ -16,11 +20,11 @@ import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
@override
Widget build(BuildContext context) {
return KeyboardVisibilityBuilder(
builder: (context, isKeyboardVisible) {
return Text(
'The keyboard is: ${isKeyboardVisible ? 'VISIBLE' : 'NOT VISIBLE'}',
);
}
builder: (context, isKeyboardVisible) {
return Text(
'The keyboard is: ${isKeyboardVisible ? 'VISIBLE' : 'NOT VISIBLE'}',
);
}
);
```
### Option 2: Within your `Widget` tree using a provider
Expand Down Expand Up @@ -92,12 +96,62 @@ Widget build(BuildContext context) {
);
}
```
By default `KeyboardDismissOnTap` will only dismiss taps not captured by other interactive `Widget`s, like buttons. If you would like to dismiss the keyboard for any tap, including taps on interactive `Widget`s, set `dismissOnCapturedTaps` to true.
```dart
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';

// Somewhere near the top of your tree...
@override
Widget build(BuildContext context) {
return KeyboardDismissOnTap(
dismissOnCapturedTaps: true,
child: MyDemoPage(),
);
}
```
The `IgnoreKeyboardDismiss` `Widget` can be used to further refine which taps do and do not dismiss the keyboard. Checkout the example app for more detail.
## Testing
Call `KeyboardVisibility.setVisibilityForTesting(value)` to set a custom value to use during `flutter test`
### Testing using mocks
`KeyboardVisibilityProvider` and `KeyboardVisibilityBuilder` accept a `controller` parameter that allow you to mock or replace the logic for reporting keyboard visibility updates.
```dart
@GenerateMocks([KeyboardVisibilityController])
void main() {
testWidgets('It reports true when the keyboard is visible', (WidgetTester tester) async {
// Pretend that the keyboard is visible.
var mockController = MockKeyboardVisibilityController();
when(mockController.onChange)
.thenAnswer((_) => Stream.fromIterable([true]));
when(mockController.isVisible).thenAnswer((_) => true);

// Build a Widget tree and query KeyboardVisibilityProvider
// for the visibility of the keyboard.
bool? isKeyboardVisible;

await tester.pumpWidget(
KeyboardVisibilityProvider(
controller: mockController,
child: Builder(
builder: (BuildContext context) {
isKeyboardVisible =
KeyboardVisibilityProvider.isKeyboardVisible(context);
return SizedBox();
},
),
),
);

// Verify that KeyboardVisibilityProvider reported that the
// keyboard is visible.
expect(isKeyboardVisible, true);
});
}
```
### Testing with a global override
Call `KeyboardVisibilityTesting.setVisibilityForTesting(false);` to set a custom value to use during `flutter test`. This is set globally and will override the standard logic of the native platform.
```dart
void main() {
testWidgets('My Test', (WidgetTester tester) async {
KeyboardVisibility.setVisibilityForTesting(true);
KeyboardVisibilityTesting.setVisibilityForTesting(true);
await tester.pumpWidget(MyApp());
});
}
Expand Down
4 changes: 0 additions & 4 deletions flutter_keyboard_visibility/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
include: package:pedantic/analysis_options.yaml

analyzer:
strong-mode:
implicit-casts: false
17 changes: 14 additions & 3 deletions flutter_keyboard_visibility/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:7.0.0'
classpath 'com.android.tools.build:gradle:7.4.2'
}
}

Expand All @@ -22,12 +22,23 @@ rootProject.allprojects {
apply plugin: 'com.android.library'

android {
compileSdkVersion 30
// Conditional for compatibility with AGP <4.2.
if (project.android.hasProperty("namespace")) {
namespace 'com.jrai.flutter_keyboard_visibility'
}

compileSdkVersion 31

defaultConfig {
minSdkVersion 16
}
lintOptions {

lint {
disable 'InvalidPackage'
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip
Loading