diegoveloper/flutter_keyboard_actions

tapOutsideToDismiss dismisses even when tapping on the field in focus or its icons

Opened this issue · 4 comments

byshy commented

Flutter doctor:

Output

[✓] Flutter (Channel stable, 1.22.4, on macOS 11.0.1 20B29 darwin-x64, locale en-PS)
• Flutter version 1.22.4 at /Users/basel/Documents/flutter
• Framework revision 1aafb3a8b9 (3 months ago), 2020-11-13 09:59:28 -0800
• Engine revision 2c956a31c0
• Dart version 2.10.4

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
• Android SDK at /Users/basel/Library/Android/sdk
• Platform android-30, build-tools 29.0.3
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
• All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.3)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 12.3, Build version 12C33
• CocoaPods version 1.10.1

[✓] Android Studio (version 4.0)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin installed
• Dart plugin version 193.7547
• Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)

[!] IntelliJ IDEA Community Edition (version 2020.2.3)
• IntelliJ at /Applications/IntelliJ IDEA CE.app
✗ Flutter plugin not installed; this adds Flutter specific functionality.
✗ Dart plugin not installed; this adds Dart specific functionality.
• For information about installing plugins, see
https://flutter.dev/intellij-setup/#installing-the-plugins

[!] VS Code (version 1.52.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
✗ Flutter extension not installed; install from
https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected device (1 available)
• Android SDK built for x86 (mobile) • emulator-5554 • android-x86 • Android 10 (API 29) (emulator)

! Doctor found issues in 2 categories.

Current behavior:

  • When enabling tapOutsideToDismiss and tapping inside the field in focus or its suffix or prefix icons, the tap is treated as a dismiss for the keyboard instead of triggering the action required, in my use case I have a password show/hide suffixIcon, each time I tap the icon with the keyboard open the state of password visibility doesn't change and the keyboard is dismissed, upon second tap the state is changed and the keyboard is opened again.

Expected behavior:

  • To neglect taps inside the field in focus (the text area itself and the suffix/prefix or both).

Minimal code for reproduction:

Code
import 'package:flutter/material.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:keyboard_actions/keyboard_actions_config.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final TextEditingController _controller = TextEditingController();
  final FocusNode _node = FocusNode();

  bool obscure = true;

  KeyboardActionsConfig _buildConfig(BuildContext context) {
    return KeyboardActionsConfig(
      keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
      keyboardBarColor: Colors.grey[200],
      nextFocus: true,
      actions: [
        KeyboardActionsItem(
          focusNode: _node,
          toolbarButtons: [
            (node) {
              return GestureDetector(
                onTap: () => node.unfocus(),
                child: Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Icon(Icons.close),
                ),
              );
            }
          ],
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('title'),
      ),
      body: KeyboardActions(
        config: _buildConfig(context),
        tapOutsideToDismiss: true,
        child: Column(
          children: <Widget>[
            TextField(
              controller: _controller,
              focusNode: _node,
              obscureText: obscure,
              decoration: InputDecoration(
                suffixIcon: IconButton(
                  onPressed: () {
                    setState(() {
                      obscure = !obscure;
                    });
                  },
                  icon: Icon(
                    obscure ? Icons.visibility : Icons.visibility_off,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

ohh, nice catch, this is the intended behavior , we are displaying a transparent container above everything , and this container has a GestureDetector.
I understand what you mean, but because we only have control on the focusNode, we don't know what's the size of the current item.

byshy commented

Maybe we can add keys to the fields and supply them to the KeyboardActionsConfig and using the onTapDown attribute of the GestureDetector get the position of the tap to neglect the touch if it was inside the draw area of the fields which can be extracted from the keys.

What do you think?

it could be, do you mind to send a PR to this package?

This is probably solved by my PR #168, I had the same issue with text selection