【问题标题】:How to avoid full page reloading when keyboard pops up?弹出键盘时如何避免整页重新加载?
【发布时间】:2019-12-15 23:36:56
【问题描述】:

观看此视频以了解问题演示 https://youtu.be/GsdWcTEbUbg

由于代码比较多,这里我尽量总结一下代码的结构。 简而言之:

Scaffold(
  appBar: AppBar(),
  body: StreamBuilder<dynamic>(
    stream: globals.chatRoomBloc.threadScreen,
    builder: (BuildContext context, AsyncSnapshot snapshot) {
      return Column(
        crossAxisAlignment:
            CrossAxisAlignment.stretch, // sticks to the keyboard
        children: <Widget>[
          Expanded(
            child: Scrollbar(
              child: ListView.builder(
                shrinkWrap: true,
                itemCount: list.length,
                itemBuilder: (BuildContext context, int index) {
                  return TileWidget();
                },
              ),
            ),
          ),
        ],
      );
    },
  ),
)

TileWidget 是有状态的,在按下回复按钮时附加 TextField 并调整小部件的大小。然后当用户点击Textfield时,键盘弹出。

现在我的问题是当键盘弹出时屏幕重新加载。

我尝试了以下解决方案:

  1. Using TextField inside a Streambuilder :我只设置一次流,即第一次加载页面时。添加新聊天或条目时,将对流进行任何更改。就我而言,这不会发生。
  2. Flutter Switching to Tab Reloads Widgets and runs FutureBuilder我不确定这是否是同一个问题,但解决方案对我没有任何改变。
  3. Issue #11895 - 我也经历过,但没有帮助。

我认为屏幕正在尝试调整大小并重新绘制以适应键盘抽屉。但由于某种原因未能这样做并重新加载所有内容。我错过了什么吗?有没有办法解决这个问题?

【问题讨论】:

  • 你找到解决办法了吗?
  • @Jatin 我发现问题是当用户单击按钮时 Streambuilder 正在触发屏幕重绘。所以我重新安排了我的代码以防止在这种情况下触发流。我对解决方案不满意,因为我不知道它是否适用于所有情况。所以我还在等待更好的解决方案。

标签: android flutter dart


【解决方案1】:

正如您提供的链接之一指出,只要应用程序的状态发生变化(即键盘弹出),您的 buildmethod 就会触发,因此请将流构建器移出它。您还可以进行一些更改。试试下面的,

在构建方法之外创建一个变量。

var myStreamBuilder;
//....
//inside initialstate method
     myStreamBuilder = StreamBuilder<dynamic>(
            stream: globals.chatRoomBloc.threadScreen,
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              return Column(
                crossAxisAlignment:
                    CrossAxisAlignment.stretch, // sticks to the keyboard
                children: <Widget>[
                  Expanded(
                    child: Scrollbar(
                      child: ListView.builder(
                        shrinkWrap: true,
                        itemCount: list.length,
                        itemBuilder: (BuildContext context, int index) {
                          return TileWidget();
                        },
                      ),
                    ),
                  ),
                ],
              );
            },
          ),

然后在你的构建方法中调用变量。

Scaffold(
  appBar: AppBar(),
  resizeToAvoidBottomInset: false, //don't forget this!
  body: myStreamBuilder
)

编辑:确保检查快照是否有数据。如果没有数据,那么应该返回一些东西,直到它有数据,这样用户就可以知道应用程序正在做什么。

此外,此属性也可能对您有所帮助。 resizeToAvoidBottomInset - https://api.flutter.dev/flutter/material/Scaffold/resizeToAvoidBottomInset.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-28
    • 2019-08-18
    • 1970-01-01
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多