简体   繁体   English

弹出键盘时如何避免整页重新加载?

[英]How to avoid full page reloading when keyboard pops up?

Check out this video for problem demo https://youtu.be/GsdWcTEbUbg查看此视频以获取问题演示https://youtu.be/GsdWcTEbUbg

As there is a large number of code, I will try to summarize the structure of the code here.由于代码比较多,这里我尽量总结一下代码的结构。 In a nutshell:简而言之:

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 is stateful, appends the TextField and resize the widget when the reply button is pressed. TileWidget 是有状态的,在按下回复按钮时附加 TextField 并调整小部件的大小。 Then when the user clicks on the Textfield, the keyboard pops up.然后当用户单击文本字段时,键盘会弹出。

Now my problem is that the screen is reloaded when the keyboard pops up.现在我的问题是当键盘弹出时屏幕重新加载。

I tried the following solutions:我尝试了以下解决方案:

  1. Using TextField inside a Streambuilder : I am setting up the stream only once, that is when the page is loaded the first time. 在 Streambuilder 中使用 TextField :我只设置一次 stream,即第一次加载页面时。 Any changes to the stream is made when a new chat or entry is added.在添加新聊天或条目时对 stream 进行任何更改。 In my case, this does not happen.就我而言,这不会发生。
  2. Flutter Switching to Tab Reloads Widgets and runs FutureBuilder I am not sure if this is the same problem, but the solution does not change anything for me. Flutter 切换到选项卡重新加载小部件并运行 FutureBuilder我不确定这是否是同一个问题,但解决方案对我没有任何改变。
  3. Issue #11895 - I went through this as well, but is not helping.问题 #11895 - 我也经历了这个,但没有帮助。

I think the screen is trying to resize and redraw to accommodate the keyboard drawer.我认为屏幕正在尝试调整大小和重绘以适应键盘抽屉。 But it is for some reason failing to do that and loading everything over again.但由于某种原因未能这样做并重新加载所有内容。 Am I missing something?我错过了什么吗? Is there a way around this?有没有解决的办法?

As one of the links you provides points out your buildmethod fires whenever the state of the app changes ie the keyboard pops up, so move the streambuilder outside of it. 正如您提供的链接之一指出的那样,只要应用程序的状态发生变化(即键盘弹出),构建方法就会触发,因此将streambuilder移出它。 There are a few more changes you could do. 您还可以进行其他更改。 Try the following, 尝试以下方法

create a variable outside of the build method. 在build方法之外创建一个变量。

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

Then in your build method call the variable. 然后在您的构建方法中调用变量。

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

EDIT: Make sure you check your snapshot that it hasData or not. 编辑:请确保您检查快照是否具有hasData。 If there is no data then something should be returned until it does have data, this way the user is informed what the app is doing. 如果没有数据,则应返回某些内容,直到它包含数据为止,这样可以通知用户应用程序在做什么。

Also this property might also be helpful to you. 此外,此属性也可能对您有所帮助。 resizeToAvoidBottomInset - https://api.flutter.dev/flutter/material/Scaffold/resizeToAvoidBottomInset.html resizeToAvoidBottomInset- https: //api.flutter.dev/flutter/material/Scaffold/resizeToAvoidBottomInset.html

I think if you use of MediaQuery So that's why Probleam create and one more Solution is Create constructor and getList again.我认为如果您使用 MediaQuery 所以这就是问题创建的原因,而另一种解决方案是再次创建构造函数和 getList。

class Demo(){
   getlist(); // get list again

} }

I faced similar issue when keyboard open or closed the page reloads basically I just delete the following line from MainActivity.XML and all works fine当键盘打开或关闭页面重新加载时我遇到了类似的问题我只是从 MainActivity.XML 中删除以下行,一切正常

android:windowSoftInputMode="adjustResize">

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM