Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

keyboard is opening when pressing on a suffix icon inside an Input decoration of a TextField #36948

Closed
chart21 opened this issue Jul 25, 2019 · 15 comments
Labels
f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Comments

@chart21
Copy link

chart21 commented Jul 25, 2019

Internal: b/171455358

Very simple bug to reproudce: Have a suffix icon inside an InputDecoration of a TextField
Expected behaviour: Pressing on the TextField opens the keyboard, pressing on the suffix icon does not (worked fine until today)
Behaviour since latest update: Keyboard also opens when pressing on the suffixIcon

Tested on: Pixel 3XL, Iphone Xs and various Android Simulators -> same behaviour

**TextField(**
          cursorColor: Colors.black,
          controller: destinationController,
          textInputAction: TextInputAction.go,
          onSubmitted: (value) {},
          **decoration: InputDecoration**(
            **suffixIcon:** Container(
                width: 67,
                child: Row(
                  children: <Widget>[
                    Container(
                      margin: EdgeInsets.only(top: 3, bottom: 3),
                      width: 2,
                      color: Colors.black,
                    ),
                    Container(
                      margin: EdgeInsets.only(bottom: 0),
                      width: 65,
                      alignment: Alignment.centerRight,
                      child: **IconButton**(
                        padding: EdgeInsets.only(bottom: 10, top: 3, right: 5),
                        iconSize: 50,
                        onPressed: **_planTripPresed**,
                        icon: Image.asset(
                          'assets/icons/cartime1.png',
                        ),
                      ),                  
                  ],
                ),
              ),
            ),
            hintText: "Set Pickup Address",
            border: InputBorder.none,
            contentPadding: EdgeInsets.only(left: 15.0, top: 15),
          ),
        ),
@HansMuller HansMuller added f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. labels Jul 25, 2019
@HansMuller
Copy link
Contributor

CC @justinmc

@shakil807g
Copy link

@HansMuller I think Input decoration, TextField and keyboard opening issues are from Alpha day and i think will never be fixed ( i had to move all the flutter app code to native ) very very disappointed by flutter team.

@justinmc
Copy link
Contributor

I was just wondering what this behavior should be while working on another PR, and I thought I came to the same conclusion as you @chart21, that taps on prefix/suffix should not pass through to the TextField. #34723 (comment)

However, I agree that's not how it behaves right now. I pasted a minimal app to reproduce the problem for both Material and Cupertino at the bottom of this comment.

I'll track down why this changed and see what it would take to fix it.

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';

void main() => runApp(SuffixApp());

class SuffixApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        textSelectionColor: Colors.purple,
        textSelectionHandleColor: Colors.purple,
      ),
      title: 'Text Field Test',
      home: Scaffold(
        appBar: AppBar(
          title: Text("TextField Test"),
        ),
        body: Center(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                CupertinoTextField(
                  suffix: Container(width: 50, height: 50, color: Colors.yellow),
                ),
                TextField(
                  decoration: InputDecoration(
                    suffixIcon: Container(width: 50, height: 50, color: Colors.red),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

@justinmc
Copy link
Contributor

Alright after going back through that PR, eventually we decided to purposely allow taps on prefix/suffix to pass through to the text field: #34723 (comment)

At first glance it looks like the Material spec shows the same behavior. If you add an icon to the interactive demo and click on it, it will activate the text field: https://material.io/design/components/text-fields.html

I know that people will want to put buttons in the prefix/suffix though, and there is no way to prevent the event from "bubbling" like on the web. You could work around this by subclassing TextField or modifying its source code. We already have some code to block taps on the clear button: https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/cupertino/text_field.dart#L81

I'm not sure what the long term solution is. Maybe some sort of parameter to TextField that says whether or not prefix/suffix pass events through to the input?

@chart21
Copy link
Author

chart21 commented Jul 25, 2019

@justinmc Thank you for your great help Justin. I think a parameter would be ideal as it is a common use case i guess. I will try to modify my code then, didn't have any success though so far with just adding a gesture detector as a parent of the textformfield. Is there a widget that consumes all input events from its parent?

@justinmc
Copy link
Contributor

There are widgets like AbsorbPointer, but confusingly they won't work in this case. The reason is that TextField uses some custom gesture detection under the hood so that it can receive gestures through the cursor and selection handles.

If you want to work around this, see my link above to how we do this for the clear button. You would need to do the same thing for your suffix.

@ralph-bergmann
Copy link
Contributor

ralph-bergmann commented Jul 26, 2019

I use this workaround:

void _cancelSearch() {
  widget.bloc.cancelSearch();

  // https://github.com/flutter/flutter/issues/36948
  // https://github.com/flutter/flutter/issues/17647
  WidgetsBinding.instance.addPostFrameCallback((_) {
    _searchFieldController.clear();
    _searchFieldFocus.unfocus();
  });
}

@chart21
Copy link
Author

chart21 commented Jul 30, 2019

thanks for the workarounds. Although they did not work for me, i fixed the problem by simply replacing the TextField with a CupertinoTextField. By default the CupertinoTextField Suffix does not open the keyboard just as the old TextField used to do.
I guess the easiest conclusion is:
If you want to open the keyboard when a user presses on the suffix -> use TextField
If you want to do something else when the user presses on the suffix -> use CupertinoTextField

Thanks for the help everyone, I will close the Issue now.

@chart21 chart21 closed this as completed Jul 30, 2019
@tiagodavi
Copy link

I am facing this same problem right now.. Is there anything I can do to solve it?

@janstol
Copy link

janstol commented Oct 3, 2019

@tiagodavi You can try to use Stack

Stack(
  alignment: Alignment.centerRight,
  children: <Widget>[
    TextField(),
    IconButton(
      icon: Icon(Icons.dialpad),
      onPressed: () {
        // do something
      },
    ),
  ],
)

@Sankaranis
Copy link

@tiagodavi You can try to use Stack

Stack(
  alignment: Alignment.centerRight,
  children: <Widget>[
    TextField(),
    IconButton(
      icon: Icon(Icons.dialpad),
      onPressed: () {
        // do something
      },
    ),
  ],
)

Hi @tiagodavi Facing invalid constant value error, when I call function on onPressed. How to solve it?

@talatkuyuk
Copy link

I have simular problem. I have a TextFormField with SuffixIcon which is IconButton. I want the keyboard stays in the same position opened/closed as it is when I pressed the SuffixIcon. I couldn't find a solution.

@ghost
Copy link

ghost commented Feb 19, 2020

I have simular problem. I have a TextFormField with SuffixIcon which is IconButton. I want the keyboard stays in the same position opened/closed as it is when I pressed the SuffixIcon. I couldn't find a solution.

Same here, I solved using Stack:

Stack(
	alignment: Alignment.centerRight,
	children: <Widget>[
	  OutlinedTextEdit(
		onChanged: _onPasswordChanged,
		label: 'Password',
		obscureText: _obscurePassword,
		keyboardType: TextInputType.text,
	  ),
	  IconButton(
		icon: _obscurePassword ? Images.eyeOff : Images.eyeShow,
		onPressed: _onObscurePasswordPressed,
	  ),
	],
  ),

@DeveloperWaybee
Copy link

SOLUTION:-

Well, this is not the right way to do this but this is working perfectly fine.

This is also working with the Cupertino text field.

SAMPLE CODE:-

import 'package:flutter/material.dart';

void main() => runApp(SuffixApp());

class SuffixApp extends StatelessWidget {
  // Focus nodes are necessary
  final textFieldFocusNode = FocusNode();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("TextField Suffix Tap Fixed"),
        ),
        body: Center(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: TextField(
              // Set Focus Node
              focusNode: textFieldFocusNode,
              decoration: InputDecoration(
                suffixIcon: GestureDetector(
                  onTap: () {
                    // Unfocus all focus nodes
                    textFieldFocusNode.unfocus();

                    // Disable text field's focus node request
                    textFieldFocusNode.canRequestFocus = false;

                    // Do your stuff
                    print("Thanks for the solution");

                    //Enable the text field's focus node request after some delay
                    Future.delayed(Duration(milliseconds: 100), () {
                      textFieldFocusNode.canRequestFocus = true;
                    });
                  },
                  child: Container(
                    width: 50,
                    height: 50,
                    color: Colors.red,
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

@lock
Copy link

lock bot commented Apr 2, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@lock lock bot locked and limited conversation to collaborators Apr 2, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

No branches or pull requests

11 participants