Textfield在Flutter 3.0.0中隐藏键盘后面

发布于 2025-01-31 18:11:40 字数 7456 浏览 5 评论 0原文

我无法获得CustomScrollview无法正常工作。

在弹奏2.13.0-0.2.pre之前,请在casurescrollview内部敲击文本字段自动在打开键盘上方的文本字段。

将我的Flutter版本降低到2.11.0-0.1.pre并在Android版本11上运行该应用程序时,ScrollView可以按预期工作 - 即使没有调整cackaffold < /code>小部件通过添加resizetoavoidbottominset:false - 当用户点击文本字段时,键盘出来了,用户可以滚动到底部。

但是,在升级为颤动3.0.0之后,情况发生了变化。当我点击文本字段并出现键盘时,我无法滚动到屏幕的底部。实际上,滚动根本不起作用。

这是一个很长的示例,其中大约有26个Textfields。敲击第25个文本字段打开涵盖该文本字段的键盘。

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: const Color(0xff185C66),
    resizeToAvoidBottomInset: true,
    body: CustomScrollView(
      shrinkWrap: true,
      clipBehavior: Clip.antiAlias,
      controller: ScrollController(),
      scrollDirection: Axis.vertical,
      slivers: [
        SliverPadding(
          padding: EdgeInsets.symmetric(horizontal: App.sidePadding),
          sliver: SliverList(
            delegate: SliverChildListDelegate.fixed([
              SafeArea(
                bottom: false,
                child: AdaptiveText(
                  'Welcome Back',
                  maxLines: 1,
                  fontSize: 24.sp,
                  maxFontSize: 25,
                  fontWeight: FontWeight.w600,
                  textColor: Colors.white,
                  textColorDark: Colors.white,
                ),
              ),
              //
              0.02.verticalh,
              //
              SizedBox(
                width: 0.71.w,
                child: AdaptiveText(
                  'Login with your email and password to continue to your account',
                  fontSize: 16.sp,
                  maxFontSize: 17,
                  textColor: Colors.white,
                  textColorDark: Colors.white,
                ),
              ),
              //
              0.045.verticalh,
              //
              TextFormField(keyboardType: TextInputType.name),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.visiblePassword),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.streetAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.datetime),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.datetime),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.datetime),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.datetime),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.phone),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.phone),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.phone),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.phone),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.phone),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.text),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.text),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.text),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.text),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.text),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.text),
              const SizedBox(height: 12),
            ]),
          ),
        ),
        //
        SliverPadding(
          padding: EdgeInsets.symmetric(horizontal: App.sidePadding),
          sliver: SliverSafeArea(
            top: false,
            sliver: SliverList(
              delegate: SliverChildListDelegate.fixed([
                SizedBox(height: 16),
                //
                TextButton(
                  onPressed: () {},
                  child: Text('Login'),
                ),
              ]),
            ),
          ),
        ),
      ],
    ),
  );
}

我谷歌搜索了此行为并找到了一些答案,

  • 添加resizetoavoidbottominset:false到脚手架窗口小
  • 部件包装casurescrollviewsinglechlidscrollview >反向属性为true
  • 添加&lt; item name =“ android:windowfullscreen”&gt; true&lt;/item&gt; styles.xml
  • 设置scrollpadding:edgeinsets.only(bottom:40) [Textfield小部件上的属性]
  • widgetsbinding.incance?.window.onmetricschanged&amp;使用setState((){})在键盘弹出时更新文本字段的底部填充物

,而其他许多其他内容只是列出了一些。

我尝试了以上所有解决方案,但是它们要么没有解决问题,要么只是与正常的滚动浏览方式相比, 都应该使用。 在检查Flutter 3.0.0 ChangElog时,我找不到有关ScrollView此更改的任何引用。

我想念什么吗? 在Flutter 3.0.0中,是否有更改casusscrollview? 知道我如何解决这个问题?

这是Flutter Doctor -v编辑的结果

[✓] Flutter (Channel stable, 3.0.0, on macOS 12.3.1 21E258 darwin-x64, locale en-NG)
    • Flutter version 3.0.0 at /Users/brendan/src/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ee4e09cce0 (2 weeks ago), 2022-05-09 16:45:18 -0700
    • Engine revision d1b9a6938a
    • Dart version 2.17.0
    • DevTools version 2.12.2

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0-rc2)
    • Android SDK at /Users/brendan/Library/android/sdk
    • Platform android-31, build-tools 33.0.0-rc2
    • ANDROID_HOME = /Users/brendan/Library/android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 13.2.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      
              

I cannot get CustomScrollView to work properly.

Before flutter 2.13.0-0.2.pre, tapping on a TextFields inside a CustomScrollView automatically adjusts the TextField above the keyboard as it opens.

On downgrading my flutter version to 2.11.0-0.1.pre and running the application on Android version 11, scrollview works as expected - even without tweaking the Scaffold widget by adding resizeToAvoidBottomInset: false - when a user taps a TextField, the keyboard comes out and the user can scroll to the bottom as it should be.

However after upgrading to Flutter 3.0.0, things changed. When i tap a TextField and the keyboard comes out, i cannot scroll to the bottom of the screen. Actually, scrolling doesn't work at all.

Here's an example of a very long Form with about 26 TextFields. Tapping the 25th TextField opens the keyboard which covers that TextField.

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: const Color(0xff185C66),
    resizeToAvoidBottomInset: true,
    body: CustomScrollView(
      shrinkWrap: true,
      clipBehavior: Clip.antiAlias,
      controller: ScrollController(),
      scrollDirection: Axis.vertical,
      slivers: [
        SliverPadding(
          padding: EdgeInsets.symmetric(horizontal: App.sidePadding),
          sliver: SliverList(
            delegate: SliverChildListDelegate.fixed([
              SafeArea(
                bottom: false,
                child: AdaptiveText(
                  'Welcome Back',
                  maxLines: 1,
                  fontSize: 24.sp,
                  maxFontSize: 25,
                  fontWeight: FontWeight.w600,
                  textColor: Colors.white,
                  textColorDark: Colors.white,
                ),
              ),
              //
              0.02.verticalh,
              //
              SizedBox(
                width: 0.71.w,
                child: AdaptiveText(
                  'Login with your email and password to continue to your account',
                  fontSize: 16.sp,
                  maxFontSize: 17,
                  textColor: Colors.white,
                  textColorDark: Colors.white,
                ),
              ),
              //
              0.045.verticalh,
              //
              TextFormField(keyboardType: TextInputType.name),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.visiblePassword),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.streetAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.datetime),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.datetime),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.datetime),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.datetime),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.phone),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.phone),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.phone),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.phone),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.phone),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.emailAddress),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.text),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.text),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.text),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.text),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.text),
              const SizedBox(height: 12),
              TextFormField(keyboardType: TextInputType.text),
              const SizedBox(height: 12),
            ]),
          ),
        ),
        //
        SliverPadding(
          padding: EdgeInsets.symmetric(horizontal: App.sidePadding),
          sliver: SliverSafeArea(
            top: false,
            sliver: SliverList(
              delegate: SliverChildListDelegate.fixed([
                SizedBox(height: 16),
                //
                TextButton(
                  onPressed: () {},
                  child: Text('Login'),
                ),
              ]),
            ),
          ),
        ),
      ],
    ),
  );
}

I googled this behavior and found some answers,

  • Adding resizeToAvoidBottomInset: false to the Scaffold widget
  • Wrapping the CustomScrollView widget with a SingleChlidScrollView and setting the reverse property to true.
  • Adding <item name="android:windowFullscreen">true</item> to styles.xml
  • Setting scrollPadding: EdgeInsets.only(bottom:40) on the TextField [A property on the TextField Widget]
  • Listening to WidgetsBinding.instance?.window.onMetricsChanged & using setState((){}) to update the bottom padding of the TextField whenever the keyboard pops out

And so many others just to list a few.

I tried all the above solutions, but they either don't fix the issue or just feels like a lot of work compared to the normal way scrollviews should work.
On checking the Flutter 3.0.0 changelog, i couldn't find any reference to this change in scrollview.

Am I missing something?
Was there a change to CustomScrollView in flutter 3.0.0?
Any idea how i can resolve this issue?

Here is the result of flutter doctor -v

[✓] Flutter (Channel stable, 3.0.0, on macOS 12.3.1 21E258 darwin-x64, locale en-NG)
    • Flutter version 3.0.0 at /Users/brendan/src/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ee4e09cce0 (2 weeks ago), 2022-05-09 16:45:18 -0700
    • Engine revision d1b9a6938a
    • Dart version 2.17.0
    • DevTools version 2.12.2

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0-rc2)
    • Android SDK at /Users/brendan/Library/android/sdk
    • Platform android-31, build-tools 33.0.0-rc2
    • ANDROID_HOME = /Users/brendan/Library/android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 13.2.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      ???? https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      ???? https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.11+0-b60-7590822)

[✓] VS Code (version 1.67.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.40.0

[✓] Connected device (3 available)
    • Redmi Note 9S (mobile) • 702f6413 • android-arm64  • Android 11 (API 30)
    • macOS (desktop)        • macos    • darwin-x64     • macOS 12.3.1 21E258 darwin-x64
    • Chrome (web)           • chrome   • web-javascript • Google Chrome 101.0.4951.64
    ! Error: j@mon is not connected. Xcode will continue when j@mon is connected. (code -13)

[✓] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!

EDIT: This issue affects Android and iOS.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千紇 2025-02-07 18:11:40

我找到了解决方案。我已经安装了flutter_screenutil软件包,并将其插入了我的小部件树上方 - 材料app上方,我还设置了usefiNheritedMediaquery:true。这阻止了小部件重建键盘状态更改之类的事情。

移动crementutils witch yecityApp下方修复了它。

I found the solution. I had installed the flutter_screenutil package and inserted it above my widget tree - above MaterialApp and I'd also set useInheritedMediaQuery: true. This prevented widget rebuilds for things like keyboard state change.

Moving the ScreenUtils widget below MaterialApp fixed it.

眼泪淡了忧伤 2025-02-07 18:11:40

您可以尝试 -

@override
Widget build(BuildContext context) {
  return Scaffold( 
    body: SingleChildScrollView(
            physics: AlwaysScrollablePhysics(),
            child: 
          ),
    ),

将其直接放置在屏幕构建的首次返回下。希望它有帮助...

You can just try -

@override
Widget build(BuildContext context) {
  return Scaffold( 
    body: SingleChildScrollView(
            physics: AlwaysScrollablePhysics(),
            child: 
          ),
    ),

Place it directly under the first return of build of the screen. Hope it helps....

烂柯人 2025-02-07 18:11:40

许多答案都表示将不同的密钥和小部件用于此目的,但是在我的情况下,crementutil软件包奏效了。
将您的主应用程序小部件(如MitalialApp)包装到crementutil中,然后制作 useInheritedMediaquery:true 。它将起作用。

Many answers are stating to use different keys and widgets for this purpose, but in my case ScreenUtil package worked.
Wrap your main app widget like MaterialApp into screenutil and make useInheritedMediaQuery: true. It will work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文