[go: nahoru, domu]

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

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

Closed
alardizabal opened this issue Jun 19, 2017 · 120 comments · Fixed by #18291
Closed

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

alardizabal opened this issue Jun 19, 2017 · 120 comments · Fixed by #18291
Assignees
Labels
a: annoyance Repeatedly frustrating issues with non-experimental functionality a: text input Entering text in a text field or keyboard related problems customer: mulligan (g3) customer: posse (eap) f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels. waiting for PR to land (fixed) A fix is in flight
Milestone

Comments

@alardizabal
Copy link

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

@alardizabal alardizabal 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 Jun 19, 2017
@eseidelGoogle
Copy link
Contributor

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

@eseidelGoogle eseidelGoogle added a: text input Entering text in a text field or keyboard related problems customer: posse (eap) labels Jun 19, 2017
@Hixie
Copy link
Contributor
Hixie commented Jun 19, 2017

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

@eseidelGoogle
Copy link
Contributor

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

@Hixie
Copy link
Contributor
Hixie commented Jun 19, 2017

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.)

@collinjackson
Copy link
Contributor
collinjackson commented Jun 21, 2017

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.

@collinjackson
Copy link
Contributor
collinjackson commented Jun 21, 2017

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.

@alardizabal
Copy link
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.

@collinjackson
Copy link
Contributor
collinjackson commented Jun 21, 2017

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.

@Hixie
Copy link
Contributor
Hixie commented Jun 27, 2017

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.

@Hixie
Copy link
Contributor
Hixie commented Jul 1, 2017

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.

@Hixie
Copy link
Contributor
Hixie commented Jul 1, 2017

Ok, figured out the bug. Now I just need to do the scrolling into view part!

@collinjackson
Copy link
Contributor

Here is an example for scrolling focused widgets into view. Should only be useful while this issue is still being worked on.

@collinjackson
Copy link
Contributor

Workaround is in place so I removed the customer blocker label, but they would still like this fixed so we can remove the workaround.

@Rishab-1065
Copy link
Rishab-1065 commented Aug 10, 2017

I am too facing this (Tapping into TextFormFields inside SingleChildScrollView causes keyboard to show and immediately hide) problem with the keyboard. It was working fine previously but right now this problem is happing with the same piece of code.

@collinjackson
Copy link
Contributor
collinjackson commented Aug 14, 2017

@Rishab-1065 if you're using the workaround I posted above, try increasing the delay on line 57 from 300ms to a larger value. There's a race condition that could probably be removed with some effort but hopefully the framework-level fix will arrive soon.

@AlexBigCheese
Copy link

I have this problem but it's a TextField in an Expanded in a Column with a Row and Divider in an Expanded in a Column.

@AlexBigCheese
Copy link

it looks like this

@eddywm
Copy link
eddywm commented Aug 9, 2018

This bug is still around.
Keyboard hiding textfield that has the focus. I have tried all the fixes in this thread and everywhere else nothing seems to work.

The tree hierachy looks like this :
Container -> ListView -> TextField

When the textfiled is at the bottom the keyboard will just hide it.

The same bug is still around in the Flutter codelabs.

@acidjazz
Copy link

@eddywm which branch/channel did you test this in? it's not in beta yet.

@eddywm
Copy link
eddywm commented Aug 10, 2018

@acidjazz I'm on the beta branch.

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v0.5.1, on Mac OS X 10.13.4 17E199, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK 27.0.3)
[✓] iOS toolchain - develop for iOS devices (Xcode 9.4)
[✓] Android Studio (version 3.1)
[✓] IntelliJ IDEA Community Edition (version 2018.1.4)
[✓] Connected devices (1 available)

@acidjazz
Copy link

@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

@dankop123
Copy link

It's fixed and text fields aren't obscured by the keyboard anymore, but I have another problem. Below text field I have button that I want to be visible when keyboard appears. Is there a way to add a offset to a point where it scrolls to make it scroll a little higher, or manually scroll so a button is above keyboard? Any other solution to this?

@zoechi
Copy link
Contributor
zoechi commented Aug 23, 2018

@dankop123 https://github.com/flutter/flutter/pull/18562/files should allow that with added scrollPadding currently only available in master

@dankop123
Copy link

@zoechi Thanks!

@joaovirgili
Copy link

I still have this issue, how can i fix it?

@zoechi
Copy link
Contributor
zoechi commented Dec 27, 2018

@joaovirgili
Please consider asking support questions in one of the other channels listed at http://flutter.io/support .

@danielmhair
Copy link
danielmhair commented Jan 10, 2019

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
        },
        ...
);

@danielmhair
Copy link
danielmhair commented Jan 10, 2019

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

@Allan-Nava
Copy link

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?

@msarkrish
Copy link
msarkrish commented Aug 12, 2019

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

@filiph filiph added the a: annoyance Repeatedly frustrating issues with non-experimental functionality label Sep 11, 2019
@Hassan-Fa
Copy link

@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

@broberts-nybble
Copy link

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

please advise?

@edwinnyawoli
Copy link

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.

@QasimQuaid
Copy link

Any update?

@hazzo
Copy link
hazzo commented Aug 12, 2020

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.

@Blacktoviche
Copy link

@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

@hazzo
Copy link
hazzo commented Aug 23, 2020

@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,
          ),
        ],
      ),
    );
  }
}

@Blacktoviche
Copy link

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

@lionuncle
Copy link

Wrap your widget inside Scaffold and set resizeToAvoidBottomInset: true,

@adekunleba
Copy link

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()

@github-actions
Copy link
github-actions bot commented Aug 3, 2021

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
a: annoyance Repeatedly frustrating issues with non-experimental functionality a: text input Entering text in a text field or keyboard related problems customer: mulligan (g3) customer: posse (eap) f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels. waiting for PR to land (fixed) A fix is in flight
Projects
Scrolling Refactor
Awaiting triage
Development

Successfully merging a pull request may close this issue.