Flutter Stream Builder срабатывает при вызове навигатора Pop или Push - PullRequest
1 голос
/ 01 июля 2019

У меня есть построитель потока на домашней / корневой странице приложения. Этот построитель потока запускается всякий раз, когда я выполняю навигацию по страницам в другом месте, что не имеет никакого отношения к самому потоку.

Насколько я понимаю, согласно здесь и здесь , когда страница вставляется / перемещается в навигаторе, это вызывает перестройку приложения, поэтому построитель потока получает и так оно и стреляет. Однако это кажется неэффективным, и есть ли способ предотвратить запуск потокового компоновщика при нажатии / нажатии страницы?

Кроме того, согласно журналам, когда я нажимаю на страницу, сначала создается страница и отображается ее, а затем запускается построитель потока. Однако виджет / страница создателя потока вообще не отображается, хотя ясно, что логи / отладчик показывают, что виджет создателя потока был возвращен. Куда это делось? Как это работает в платформе Flutter?

Ниже приведен полный код и журналы. Код использует Firebase auth в качестве потокового компоновщика.

Код:

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: AppHomePage(),
    );
  }
}

class AppHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final FirebaseAuth auth = FirebaseAuth.instance;
    return StreamBuilder<FirebaseUser>(
      stream: auth.onAuthStateChanged,
      builder: (_, AsyncSnapshot<FirebaseUser> snapshot) {
        if (snapshot.connectionState == ConnectionState.active) {
          final FirebaseUser user = snapshot.data;
          if (user == null) {
            debugPrint("User is NULL.");
            return SignInPage();
          } else {
            debugPrint("User exists.");
            return MainPage();
          }
        } else {
          debugPrint("In waiting state.");
          return Scaffold(
            body: Center(
              child: CircularProgressIndicator(),
            ),
          );
        }
      },
    );
  }
}

class MainPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    debugPrint("Building main page.");
    return Scaffold(
      body: Center(
        child: Text("Welcome to our app!"),
      ),
    );
  }
}

class SignInPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    debugPrint("Building sign-in page.");
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            FlatButton(
              color: Colors.blue,
              child: Text('Sign In as Anonymous'),
              onPressed: () {
                debugPrint("Anonymous");
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => MainPage()),
                );
              },
            ),
            FlatButton(
              color: Colors.red,
              child: Text('Sign In with Google'),
              onPressed: () => debugPrint("Google"),
            ),
          ],
        ),
      ),
    );
  }
}

Журналы, где 4-ая строка указывает на нажатие кнопки для выполнения navigator.pop ():

I/flutter (22339): In waiting state.
I/flutter (22339): User is NULL.
I/flutter (22339): Building sign-in page.
I/flutter (22339): Anonymous
I/flutter (22339): Building main page.
I/flutter (22339): User is NULL.
I/flutter (22339): Building sign-in page.

1 Ответ

2 голосов
/ 01 июля 2019

Я часами разбираюсь, как это исправить.Оказывается, AppHomePage нужно расширить StatefulWidget вместо StatelessWidget.

Не знаю почему, но это работает.

...