3

I have created an example project that resembles Navigate to a new screen and back example. The only difference that I have TextField with autofocus: true on every screen:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Navigation Basics',
    home: FirstScreen(),
  ));
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("FirstScreen build");
    return Scaffold(
      body: Column(
        children: <Widget>[
          RaisedButton(
            child: Text('Next screen'),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => SecondScreen()),
              );
            },
          ),
          TextField(
            decoration: InputDecoration(),
            onEditingComplete: () {},
            autofocus: true,
          )
        ],
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("SecondScreen build");
    return Scaffold(
      body: Column(
        children: <Widget>[
          RaisedButton(
            child: Text('Next screen'),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => ThirdScreen()),
              );
            },
          ),
          TextField(
            decoration: InputDecoration(),
            onEditingComplete: () {},
            autofocus: true,
          )
        ],
      ),
    );
  }
}

class ThirdScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("ThirdScreen build");
    return Scaffold(
      body: Column(
        children: <Widget>[
          RaisedButton(
            child: Text('Next screen'),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => FourthScreen()),
              );
            },
          ),
          TextField(
            decoration: InputDecoration(),
            onEditingComplete: () {},
            autofocus: true,
          )
        ],
      ),
    );
  }
}

class FourthScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("FourthScreen build");
    return Scaffold(
      body: Column(
        children: <Widget>[
          TextField(
            decoration: InputDecoration(),
            onEditingComplete: () {},
            autofocus: true,
          )
        ],
      ),
    );
  }
}

When I navigate from ThirdScreen to FourthScreen my log looks like this:

I/flutter ( 7523): FourthScreen build
I/flutter ( 7523): SecondScreen build
I/flutter ( 7523): ThirdScreen build
I/flutter ( 7523): FourthScreen build
I/flutter ( 7523): SecondScreen build
I/flutter ( 7523): ThirdScreen build
I/flutter ( 7523): FourthScreen build
  1. Why after FourthScreen is built at the first time SecondScreen, ThirdScreen and FourthScreen build is called again?
  2. Why screens in the backstack are being reguild in the keyboard pops out?
  3. Why FirstScreen is not being rebuild?
Vadims Savjolovs
  • 2,618
  • 1
  • 26
  • 51
  • check this : https://stackoverflow.com/questions/52249578/how-to-deal-with-unwanted-widget-build – diegoveloper Jan 14 '19 at 17:09
  • Possible duplicate of [How to deal with unwanted widget build?](https://stackoverflow.com/questions/52249578/how-to-deal-with-unwanted-widget-build) – ishaan Jan 14 '19 at 19:32
  • You should always be prepared for your build() method to be called 60 times a second. If you start with that design, everything else will fall into place. – Randal Schwartz Jan 27 '19 at 18:39

2 Answers2

0

I tried running the repro you've provided and I wasn't able to replicate the issue you've reported. Previous screens don't get rebuilt after navigating to the next screen.

demo

flutter doctor

[✓] Flutter (Channel stable, 1.22.3, on Mac OS X 10.15.7 19H2, locale en)
    • Flutter version 1.22.3
    • Framework revision 8874f21e79 (5 days ago), 2020-10-29 14:14:35 -0700
    • Engine revision a1440ca392
    • Dart version 2.10.3

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Platform android-29, build-tools 29.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.0.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.0.1, Build version 12A7300
    • CocoaPods version 1.9.0

[!] Android Studio (version 4.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)

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

[✓] Connected device (2 available)
    • AOSP on IA Emulator (mobile) • emulator-5554                        • android-x86 • Android 9 (API 28) (emulator)
    • iPhone 11 (mobile)           • 216904B4-E876-4AC5-9BCF-F77CD19B9338 • ios         • com.apple.CoreSimulator.SimRuntime.iOS-14-0 (simulator)

If you're still having issues, please provide a minimal repro along with the steps to replicate the behavior and file it here http://github.com/flutter/flutter/issues/

Omatt
  • 8,564
  • 2
  • 42
  • 144
0

I was facing the same problem I resolved this using the below method.

  1. USe provider to get current page.
  2. Create a variable of String type route(route is variable name)
  3. call the provider on each screen and assign that screen name.
  4. Call provider on screen, or on menu drawer or anywhere from where you are navigating.

Provider class code

  class RouteProvider with ChangeNotifier {
  String _route = "initial";

  String get route => _route;
  set route(String data) {
    this._route = data;
    notifyListeners();
  }
}

assigning rout/screen name to provider inside build()

 final route = context.watch<RouteProvider>().route = "OffersView";

On consumer screen inside build

 final route = context.watch<RouteProvider>().route;
  if (route != "OffersView") {
                      Navigator.pushAndRemoveUntil(
                          context,
                          MaterialPageRoute(
                              builder: (Context) => OffersPage()),
                          (route) => false);
                    }
Khurram
  • 173
  • 7