Ayu*_*har 2 dart flutter flutter-dependencies
我正在使用提供程序来管理我的应用程序状态。这是我的实现方式。
催眠药
class _HypnoseAppState extends State<HypnoseApp> {
@override
Widget build(BuildContext context) {
UserService userService = UserService();
AudioUtilService audioUtilService = AudioUtilService();
return MultiProvider(
providers: [
ChangeNotifierProvider<UserService>.value(
value: userService,
),
ChangeNotifierProvider<AudioUtilService>.value(
value: audioUtilService,
)
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: Globals.title,
theme: ThemeData(primarySwatch: Colors.cyan),
darkTheme: ThemeData.dark(),
initialRoute: '/',
routes: {
'/': (BuildContext context) => WelcomeScreen(userService),
'/home': (BuildContext context) => HomePageSwitcher(),
'/audiocreate': (BuildContext context) => AudioCreateScreen()
}),
);
}
}
Run Code Online (Sandbox Code Playgroud)
home_switcher.dart
class HomePageSwitcher extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<UserService>(
builder: (BuildContext context, UserService userService, Widget child) {
return Scaffold(
appBar: AppBar(),
drawer: Drawer(
child: Column(
children: <Widget>[
UserAccountsDrawerHeader(
accountEmail: Text(userService.loggedInUser.email),
accountName: Text(userService.loggedInUser.name),
currentAccountPicture:
Image.network(userService.loggedInUser.avatar),
)
],
),
),
body: Center(
child: RaisedButton(
child: Text('Sign out'),
onPressed: () async {
await userService.signOut();
Navigator.pushNamed(context, '/');
},
),
));
},
);
}
}
Run Code Online (Sandbox Code Playgroud)
user_service.dart
class UserService extends ChangeNotifier {
// Get auth instances
final GoogleSignIn _googleSignIn = GoogleSignIn();
final FirebaseAuth _auth = FirebaseAuth.instance;
// Store reference of user collection
final CollectionReference userDb = Firestore.instance.collection('user');
// Master instance of logged in user
User _loggedInUser;
// Getter to access loggedInUser
User get loggedInUser {
return _loggedInUser;
}
PublishSubject<AuthState> _authStateSubject = PublishSubject();
.... other code
Run Code Online (Sandbox Code Playgroud)
现在的问题是,每次我在首页上热加载时,我都会开始收到NoSuchMethodError,因为它说在null上调用了诸如电子邮件,名称等属性,这意味着状态丢失了。我该如何克服呢?难道我做错了什么?
您不应该使用ChangeNotifierProvider.value。而是使用默认构造函数:
ChangeNotifierProvider(
builder: (_) => UserService(),
)
Run Code Online (Sandbox Code Playgroud)
否则,您的构建方法是不纯的,您将遇到“ 如何处理不需要的小部件构建?
小智 6
构建方法的设计方式应该是纯粹的/没有副作用。这是因为许多外部因素可以触发新的小部件构建,例如:
Route pop/push
Screen resize, usually due to keyboard appearance or orientation change
Parent widget recreated its child
An InheritedWidget the widget depends on (Class.of(context) pattern) change
Run Code Online (Sandbox Code Playgroud)
这意味着 build 方法不应触发 http 调用或修改任何状态。
这与问题有什么关系?
您面临的问题是您的构建方法有副作用/不纯,使无关的构建调用变得麻烦。
与其阻止构建调用,您应该使构建方法纯,以便可以随时调用而不会产生影响。
在您的示例中,您将小部件转换为 StatefulWidget,然后将该 HTTP 调用提取到状态的 initState:
ChangeNotifierProvider(
create: (_) => UserService(),
),
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
511 次 |
| 最近记录: |