and1990
and1990

Reputation: 55

Using StreamBuilder and Navigator in my flutter app, but the first page builds twice

guys. I am using StreamBuilder dealing with asynchronous data.

Here is a demo that a button on the first page, click the button will navigate to the second page. The full code is below.

import 'package:flutter/material.dart';
import 'dart:async' show StreamController;

void main() {
  runApp(
    new MaterialApp(
      title: 'First Page',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new FirstPage(),
    ),
  );
}

class FirstPage extends StatelessWidget {
  final StreamController<String> _streamController = StreamController<String>();

  @override
  Widget build(BuildContext context) {
    print('first page start to build ..................');
    StreamBuilder builder = new StreamBuilder(
        stream: _streamController.stream,
        builder: (context, asyncSnapshot) {
          if (asyncSnapshot.hasData) {
            print('first page data returned ..................');
            return RaisedButton(
              child: Text('go to the second page'),
              onPressed: () {
                print('navigate to second page ..................');
                  Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => SecondPage()),
                );
              },
            );
          } else {
            return Text('waitting to update');
          }
        });
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('First Page'),
      ),
      body: Column(
        children: <Widget>[
          RaisedButton(
            child: Text('update state'),
            onPressed: () {
              _streamController.add('hello world');
            },
          ),
          builder,
        ],
      ),
    );
  }

  dispose() {
    _streamController.close();
  }
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print('second page start to build ..................');
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Second Page'),
      ),
      body: Text('this is second page'),
    );
  }
}

Here are the operation steps:

  1. click the 'update state ' button on the first page.
  2. the button 'go to the second page' will show.
  3. click 'go to the second page' button will navigate to the second page.
  4. then click the button in the left corner of the second page to go back to the first page.

The console will show something like that:

I/flutter ( 3674): first page start to build ..................
Reloaded 1 of 487 libraries in 1,734ms.
I/flutter ( 3674): first page data returned ..................
I/flutter ( 3674): navigate to second page ..................
I/flutter ( 3674): second page start to build ..................
I/flutter ( 3674): first page data returned ..................
I/flutter ( 3674): first page data returned ..................

My question is:

  1. The first page will build again after the second page build. Why?
  2. And when I back to the first page, the first page will build again, is it normal?

Please help me.

Upvotes: 3

Views: 3982

Answers (1)

R&#233;mi Rousselet
R&#233;mi Rousselet

Reputation: 277037

This is the expected behavior.

The number of times a widget is built should never change the behavior of an application, and it at most a performance optimization.

If this is causing you any kind of issue, then you're likely doing something wrong inside build method. In which case, you might want to read How to deal with unwanted widget build?

Upvotes: 3

Related Questions