Skip to content

Scroll text fields into view when keyboard comes up and obscures them #10826

Closed

Description

@alardizabal

I have several TextFormFields in a ListView, and it seems that if I tap into fields near the bottom (fields that would be obscured by the keyboard), the keyboard will appear and then immediately hide. I’m guessing it’s because it’s scrolling the list view which then causes the keyboard to dismiss. I've modified the flutter gallery text field demo and attached a video. Happens on both iOS and Android.

text_field_movie.zip

Activity

  1. changed the title [-]Tapping into TextFormFields inside ListView cause keyboard to show and immediately hide[/-] [+]Tapping into TextFormFields inside ListView causes keyboard to show and immediately hide[/+] on Jun 19, 2017
  2. eseidelGoogle commented on Jun 19, 2017

    @eseidelGoogle
    Contributor

    @Hixie @abarth this sounds familiar, do we already have this tracked/understood somewhere else?

  3. Hixie commented on Jun 19, 2017

    @Hixie
    Contributor

    This is basically the same bug as #105, #170, #172, #188.

  4. eseidelGoogle commented on Jun 19, 2017

    @eseidelGoogle
    Contributor

    @Hixie is there anything Posse can do to work around this bug? This specific instantiation is currently considered as a high priority issue.

  5. Hixie commented on Jun 19, 2017

    @Hixie
    Contributor

    Not really. Mark it a blocker and I'll fix it in the next week or two. (I'm working on deep linking bugs right now, which I understand are also a high priority.)

  6. self-assigned this
    on Jun 20, 2017
  7. collinjackson commented on Jun 21, 2017

    @collinjackson
    Contributor

    There's a workaround that should get around this:

    new ListView(
      reverse: true,
      children: <Widget>[
        // put your text fields here
      ].reversed.toList(),
    ),
    

    This is inspired by how the Flutter UI codelab works (we want to use the bottom of the ListView as the scroll anchor instead of the top, so that the software keyboard will shift the list contents upwards).

    Unfortunately, it can introduce a new bug if the scrolling pushes the text fields upwards and they end up getting hidden by the top. If you only have a few text fields and they're at the bottom of your ListView, this might be just fine, but it would still be a problem if you have a lot of text fields.

  8. collinjackson commented on Jun 21, 2017

    @collinjackson
    Contributor

    You can use a SingleChildScrollView with a Column instead of a ListView to prevent the keyboard from dismissing. It won't solve the problem of the text field being hidden by the keyboard, but it would at least allow the user to scroll the field into view and then fill it out.

  9. alardizabal commented on Jun 21, 2017

    @alardizabal
    Author

    Thanks @collinjackson . The SingleChildScrollView workaround makes my form useable. The fix would be great so that the text fields aren't hidden requiring the user to scroll the field into view.

  10. collinjackson commented on Jun 21, 2017

    @collinjackson
    Contributor

    OK, good. Sounds like it's no longer blocking.

    @Hixie is going to work on preventing fields from being scrolled offscreen by the keyboard as part of his work on #105 next week. Once that is done, we can close this bug and you'll be able to go back to using ListView.

  11. Hixie commented on Jun 27, 2017

    @Hixie
    Contributor

    I've begun work on this issue.

    • Teach RenderSliverMultiBoxAdaptor to keep children alive.
    • Test that RenderSliverMultiBoxAdaptor knows how to keep children alive.
    • Test that RenderSliverMultiBoxAdaptor knows how to drop kept-alive children when they go away.
    • Teach RenderSliverMultiBoxAdaptor to describe its children now that it has two sets of children.
    • Test RenderSliverMultiBoxAdaptor description.
    • KeepAlive widget.
    • Test KeepAlive widget.
    • KeepAliveAutomatically widget.
    • Test KeepAliveAutomatically widget.
    • Automatically wrap SliverList and SliverGrid children in KeepAliveAutomatically widgets.
    • Test that the automatic wrapping works.
    • Dispatch events to KeepAliveAutomatically when focused.
    • Test that we dispatch events to KeepAliveAutomatically when focused.
    • Dispatch events to KeepAliveAutomatically when splashing. (Splashes are lost if you scroll their row off the screen #105)
    • Test that we ispatch events to KeepAliveAutomatically when splashing.
    • Dispatch events to KeepAliveAutomatically when dismissing. (When an item in a lazy list is being dismissed, we should keep it alive #172)
    • Test that we dispatch events to KeepAliveAutomatically when dismissing.
    • Provide a way to figure out the actual location of kept-alive children.
    • Actually move the focused item into view when the list is occluded.
    • Test moving of focused item into view.
  12. Hixie commented on Jul 1, 2017

    @Hixie
    Contributor

    I've a patch that does almost all of this. The two remaining bits are actually scrolling the text field into view, and handling text fields that have decorations because the reparenting is causing some sort of bug in my code and prematurely ejecting the row.

  13. 118 remaining items

  14. Allan-Nava commented on May 7, 2019

    @Allan-Nava

    Actually, there was a few issues with this after testing, but adding resizeToAvoidBottomPadding: true to the Scaffold fixed mine.

    How can I put my form centered and when the keyboard is shown put all up of the keyboard?

  15. msarkrish commented on Aug 12, 2019

    @msarkrish

    You can use a SingleChildScrollView with a Column instead of a ListView to prevent the keyboard from dismissing. It won't solve the problem of the text field being hidden by the keyboard, but it would at least allow the user to scroll the field into view and then fill it out.

    Thank You Brother. you solved my problem i had the issue like my error messages are gone, i have more form fields in form after clicking button i showing error to user, after scrolling to down and scroll upwards my errors are missing.
    My Error widget tree:
    Form -> Listview
    Correct widget tree:
    Form -> SingleChildScrollView -> Column

  16. added
    a: annoyanceRepeatedly frustrating issues with non-experimental functionality
    on Sep 11, 2019
  17. Hassan-Fa commented on Dec 25, 2019

    @Hassan-Fa

    @eddywm i think you have to wait until its in that branch, i believe this fix is only in the dev branch.

    if you want, try flutter channel dev and then recompile/etc

    @acidjazz
    not in master yet ?
    cause I still have this issue on master

  18. broberts-nybble commented on Jan 15, 2020

    @broberts-nybble

    on the latest version, was working without any issues now appears to have returned.

    please advise?

  19. edwinnyawoli commented on May 12, 2020

    @edwinnyawoli

    In my case I realized when I had windowFullscreen style attribute of the LaunchTheme set to true
    <item name="android:windowFullscreen">true</item>,
    SystemChrome.* methods did not work. These methods started working as expected when I set it to false.

  20. QasimQuaid commented on Aug 11, 2020

    @QasimQuaid

    Any update?

  21. hazzo commented on Aug 12, 2020

    @hazzo

    Don't know if this is still an issue, but it was for me today with the stable sdk branch. I noticed that the SingleChildScrollView was moving when the text field was being focused and almost outside of the viewport. So I thought that maybe the keyboard height was missing to the scrolling position. And indeed it was, I added the text field the property scrollPadding with the bottom view inset size and it worked like charm (MediaQuery.of(context).viewInsets.bottom). Hope it helps.

  22. Blacktoviche commented on Aug 22, 2020

    @Blacktoviche

    @hazzo Can you explain with little code please?
    Because I'm having the same issue with keyboard hide TextField when pop up and I have tried every single solution exists here and in stackoverflow but no luck.
    The problem is what the hell is wrong with the code
    SingleChildScrollView, ListView , Column combination but no luck

  23. hazzo commented on Aug 23, 2020

    @hazzo

    @Blacktoviche something like this should do the trick:

    class ColumnScrollView extends StatelessWidget {
      final List<Widget> children;
      final EdgeInsets padding;
      final CrossAxisAlignment crossAxisAlignment;
      final MainAxisAlignment mainAxisAlignment;
      final MainAxisSize mainAxisSize;
    
      const ColumnScrollView(
          {Key key,
          @required this.children,
          this.crossAxisAlignment = CrossAxisAlignment.center,
          this.mainAxisAlignment = MainAxisAlignment.start,
          this.mainAxisSize = MainAxisSize.max,
          this.padding = const EdgeInsets.symmetric(horizontal: 20.0)})
          : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return LayoutBuilder(
          builder: (BuildContext ctx, BoxConstraints viewportConstrains) {
            return SingleChildScrollView(
              child: ConstrainedBox(
                  constraints: BoxConstraints(minHeight: viewportConstrains.maxHeight),
                  child: IntrinsicHeight(
                    child: Padding(
                      padding: padding,
                      child: Column(
                        children: children,
                        crossAxisAlignment: crossAxisAlignment,
                        mainAxisAlignment: mainAxisAlignment,
                      ),
                    ),
                  )),
            );
          },
        );
      }
    }
    
    
    class TestWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        var keyboardHeight = MediaQuery.of(context).viewInsets.bottom;
        return Scaffold(
          body: ColumnScrollView(
            children: [
              SizedBox(
                height: 400,
              ),
              TextField(
                  scrollPadding: EdgeInsets.symmetric(vertical: keyboardHeight + 20) // 20 is default widget scroll padding,
                  ),
              SizedBox(
                height: 400,
              ),
            ],
          ),
        );
      }
    }
    
  24. Blacktoviche commented on Aug 24, 2020

    @Blacktoviche

    Thankx @hazzo but unfortunately it didn't work. But my code worked fine after little investigating about the problem cause.
    please refer to this 64392#issuecomment-678997571 for more details

  25. lionuncle commented on Jan 20, 2021

    @lionuncle

    Wrap your widget inside Scaffold and set resizeToAvoidBottomInset: true,

  26. adekunleba commented on Apr 10, 2021

    @adekunleba

    There's a workaround that should get around this:

    new ListView(
      reverse: true,
      children: <Widget>[
        // put your text fields here
      ].reversed.toList(),
    ),
    

    This is inspired by how the Flutter UI codelab works (we want to use the bottom of the ListView as the scroll anchor instead of the top, so that the software keyboard will shift the list contents upwards).
    Unfortunately, it can introduce a new bug if the scrolling pushes the text fields upwards and they end up getting hidden by the top. If you only have a few text fields and they're at the bottom of your ListView, this might be just fine, but it would still be a problem if you have a lot of text fields.

    Thank you for posting your reply @collinjackson. I had the same problem. However, I was using ListView.builder, so it wasn't just like you did, but this workaround worked for me:

    ListView.builder(
            reverse: true, // <======  ADDED THIS
            itemCount: tasks.length,
            itemBuilder: (context, index) {
              index = (index - tasks.length).abs(); // <======  ADDED THIS
              // Keep same code as before
            },
            ...
    );
    

    This worked just fine, kept the list in same order. However need to do a +1 in the index reassignment to handle out of index.
    index = (index + 1 - tasks.length).abs()

  27. github-actions commented on Aug 3, 2021

    @github-actions

    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.

  28. locked as resolved and limited conversation to collaborators on Aug 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions