Флаттер провайдер работает каждый раз, даже без вызова уведомителя - PullRequest
0 голосов
/ 04 апреля 2020

Я разрабатываю кроссплатформенное приложение с использованием флаттера.

Я слышал, что root провайдер наблюдает за всем пользовательским интерфейсом, но если я не вызываю notifylistener (), он не вызывает build (), когда данные имеют был изменен.

Я никогда не вызываю notifylistener (), но flutter всегда вызывает функцию build () StartupView, если представление было изменено с StartupView на MenuView.

как я могу предотвратить вызов build ( ) функция запуска Просмотр по провайдеру?

class Router {
  static Route<dynamic> generateRoute(RouteSettings settings) {
    switch (settings.name) {
      case loginRoute:
        return MaterialPageRoute(
            settings: settings, builder: (_) => LoginView());
      case pinPutRoute:
        var data = settings.arguments as int;
        return MaterialPageRoute(
            settings: settings, builder: (_) => PinPutView(pinType: data,));
      case menuRoute:
        return MaterialPageRoute(
            settings: settings, builder: (_) => MenuView());
      ....
}
class Settings with ChangeNotifier {
  // I swear Settings class never call notifylistener(). it's only for storing token, some private keys
  String _fcmtok = null;
  String _devicetok = null;
  String _servertok = null;
  String _pin = null;
  int _latest_access_time = 0;
  bool _phoneAuth = false;
  SharedPreferences _prefs;

  SharedPreferences getPrefs() => _prefs;
  String getFcmToken() => this._fcmtok;
  String getDeviceToken() => this._devicetok;
  String getServerToken() => this._servertok;
  int getLatestAccessTime() => this._latest_access_time;

  ... functions that using SharedPreferences
}

class MainApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<Settings>(create: (_) => Settings()),
      ],
      child: MaterialApp(
        onGenerateRoute: Router.generateRoute,
        initialRoute: startupRouter, // it is going to move to StartupView
        theme: ThemeData.dark(),
      ),
    );
  }
}


class StartupView extends StatefulWidget {
  StartupView({Key key}) : super(key: key);

  @override
  State createState() {
    return _StartupView();
  }
}

class _StartupView extends State<StartupView> {
    Future<int> setup;
    final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();

      @override
      void initState() {
        this.setup = initalize();
        super.initState();
      }

      @override
      Widget build(BuildContext context) {

        print('startup view ');

        return FutureBuilder<int>(
            future: this.setup,
            builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
              if (!snapshot.hasData) {
                print(snapshot.error.toString());
                return Scaffold(body: WaitingComponent());
              } else {
                if (!snapshot.hasError) {
                  if (snapshot.data == PHONE_AUTH_NOK) {
                    return LoginView();
                  } else if (snapshot.data == PIN_AUTH_NOK){
                    return PinPutView(pinType: HAS_PIN,);
                  }
                  else if (snapshot.data == OK) {
                    return MenuView(); // if i move to MenuView(), print('startup view '); is fired
                  }
                  else {
                    return ErrorView();
                  }
                }
              }
            });
      }

      Future<int> initalize() async {
        // true is auto auth, false is no auth
        print('init start');

        Settings settings = Provider.of<Settings>(context, listen: false);

        await settings.initalizeSharedPreferences();
        await firebaseCloudMessaging_Listeners(settings);
        await initPlatformState(settings);

        print('init done');
      }
    }

class MenuView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Information information = Provider.of<Information>(context);
    Settings settings = Provider.of<Settings>(context);
    Order order = Provider.of<Order>(context);
    var mediaQuery = MediaQuery.of(context);

    ... UI Codes
  }
}
...