5

Check out this video for problem demo 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. 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. Any changes to the stream is made when a new chat or entry is added. 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.
  3. Issue #11895 - I went through this as well, but is not helping.

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 ?

vzurd
  • 1,416
  • 2
  • 15
  • 37
  • Did you find any solution? – Jatin Aug 11 '19 at 17:38
  • 1
    @Jatin I figured out the problem was that the Streambuilder is triggering the screen to be redrawn when the user clicks the button. So I rearranged my code to prevent stream from being triggered in such scenarios. I am not happy with the solution though because I don't know if it would hold in all cases. So I am still waiting for a better solution. – vzurd Aug 12 '19 at 15:54

3 Answers3

4

As one of the links you provides points out your buildmethod fires whenever the state of the app changes i.e the keyboard pops up, so move the streambuilder outside of it. There are a few more changes you could do. Try the following,

create a variable outside of the build method.

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

F-1
  • 2,887
  • 20
  • 28
1

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

android:windowSoftInputMode="adjustResize">
AHMAD_AR
  • 76
  • 1
  • 7
0

I think if you use of MediaQuery So that's why Probleam create and one more Solution is Create constructor and getList again.

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

}

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 02 '22 at 15:05