Я разрабатываю кроссплатформенное приложение с использованием флаттера.
Я слышал, что 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
}
}