我正在使用Flutter BloC编写我的登录&注册&确认页面。
当我进入“注册页面”时(当我点击该按钮时),我得到了错误。
错误:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY
╞═══════════════════════════════════════════════════════════
The following ProviderNotFoundException was thrown building
KeyedSubtree-[GlobalKey#76df5]:
Error: Could not find the correct Provider<AuthCubit> above this
_InheritedProviderScope<SignUpBloc?> Widget
This happens because you used a `BuildContext` that does not include the
provider
of your choice. There are a few common scenarios:
- You added a new provider in your `main.dart` and performed a hot-reload.
To fix, perform a hot-restart.
- The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.
- You used a `BuildContext` that is an ancestor of the provider you are trying
to read.
Make sure that _InheritedProviderScope<SignUpBloc?> is under your
MultiProvider/Provider<AuthCubit>.
This usually happens when you are creating a provider and trying to read it
immediately.
For example, instead of:
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>().toString()),
);
}
consider using `builder` like so:
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the
provider
builder: (context, child) {
// No longer throws
return Text(context.watch<Example>().toString());
}
);
}
If none of these solutions work, consider asking for help on StackOverflow:
https://stackoverflow.com/questions/tagged/flutter
The relevant error-causing widget was:
Scaffold
Scaffold:file:///Users/kelly_hung/study_savvy_app/lib/screens/sign_up.dart:15:
12
When the exception was thrown, this was the stack:
#0 Provider._inheritedElementOf (package:provider/src/provider.dart:343:7)
#1 Provider.of (package:provider/src/provider.dart:293:30)
#2 ReadContext.read (package:provider/src/provider.dart:649:21)
#3 main.<anonymous closure>.<anonymous closure>
(package:study_savvy_app/main.dart:81:112)
#4 _CreateInheritedProviderState.value
(package:provider/src/inherited_provider.dart:736:36)
#5 _InheritedProviderScopeElement.value
(package:provider/src/inherited_provider.dart:590:33)
#6 Provider.of (package:provider/src/provider.dart:303:37)
#7 ReadContext.read (package:provider/src/provider.dart:649:21)
#8 _BlocListenerBaseState.initState
(package:flutter_bloc/src/bloc_listener.dart:143:36)
#9 StatefulElement._firstBuild
(package:flutter/src/widgets/framework.dart:5219:55)
#10 ComponentElement.mount
(package:flutter/src/widgets/framework.dart:5062:5)
#11 SingleChildWidgetElementMixin.mount (package:nested/nested.dart:222:11)
#12 Element.inflateWidget
(package:flutter/src/widgets/framework.dart:3971:16)
#13 MultiChildRenderObjectElement.inflateWidget
(package:flutter/src/widgets/framework.dart:6570:36)
#14 MultiChildRenderObjectElement.mount
(package:flutter/src/widgets/framework.dart:6582:32)
... Normal element mounting (25 frames)
#39 Element.inflateWidget
(package:flutter/src/widgets/framework.dart:3971:16)
#40 MultiChildRenderObjectElement.inflateWidget
(package:flutter/src/widgets/framework.dart:6570:36)
#41 MultiChildRenderObjectElement.mount
(package:flutter/src/widgets/framework.dart:6582:32)
... Normal element mounting (134 frames)
#175 Element.inflateWidget
(package:flutter/src/widgets/framework.dart:3971:16)
#176 MultiChildRenderObjectElement.inflateWidget
(package:flutter/src/widgets/framework.dart:6570:36)
#177 MultiChildRenderObjectElement.mount
(package:flutter/src/widgets/framework.dart:6582:32)
... Normal element mounting (178 frames)
#355 Element.inflateWidget
(package:flutter/src/widgets/framework.dart:3971:16)
#356 MultiChildRenderObjectElement.inflateWidget
(package:flutter/src/widgets/framework.dart:6570:36)
#357 Element.updateChild (package:flutter/src/widgets/framework.dart:3708:18)
#358 RenderObjectElement.updateChildren
(package:flutter/src/widgets/framework.dart:6153:32)
#359 MultiChildRenderObjectElement.update
(package:flutter/src/widgets/framework.dart:6595:17)
#360 Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#361 ComponentElement.performRebuild
(package:flutter/src/widgets/framework.dart:5111:16)
#362 StatefulElement.performRebuild
(package:flutter/src/widgets/framework.dart:5251:11)
#363 Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7)
#364 StatefulElement.update
(package:flutter/src/widgets/framework.dart:5274:5)
#365 Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#366 ComponentElement.performRebuild
(package:flutter/src/widgets/framework.dart:5111:16)
#367 Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7)
#368 ProxyElement.update (package:flutter/src/widgets/framework.dart:5417:5)
#369 Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#370 ComponentElement.performRebuild
(package:flutter/src/widgets/framework.dart:5111:16)
#371 Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7)
#372 ProxyElement.update (package:flutter/src/widgets/framework.dart:5417:5)
#373 _InheritedNotifierElement.update
(package:flutter/src/widgets/inherited_notifier.dart:107:11)
#374 Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#375 ComponentElement.performRebuild
(package:flutter/src/widgets/framework.dart:5111:16)
#376 StatefulElement.performRebuild
(package:flutter/src/widgets/framework.dart:5251:11)
#377 Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7)
#378 StatefulElement.update
(package:flutter/src/widgets/framework.dart:5274:5)
#379 Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#380 ComponentElement.performRebuild
(package:flutter/src/widgets/framework.dart:5111:16)
#381 Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7)
#382 ProxyElement.update (package:flutter/src/widgets/framework.dart:5417:5)
#383 _InheritedNotifierElement.update
(package:flutter/src/widgets/inherited_notifier.dart:107:11)
#384 Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#385 ComponentElement.performRebuild
(package:flutter/src/widgets/framework.dart:5111:16)
#386 StatefulElement.performRebuild
(package:flutter/src/widgets/framework.dart:5251:11)
#387 Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7)
#388 StatefulElement.update
(package:flutter/src/widgets/framework.dart:5274:5)
#389 Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#390 ComponentElement.performRebuild
(package:flutter/src/widgets/framework.dart:5111:16)
#391 StatefulElement.performRebuild
(package:flutter/src/widgets/framework.dart:5251:11)
#392 Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7)
#393 StatefulElement.update
(package:flutter/src/widgets/framework.dart:5274:5)
#394 Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#395 SingleChildRenderObjectElement.update
(package:flutter/src/widgets/framework.dart:6442:14)
#396 Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#397 SingleChildRenderObjectElement.update
(package:flutter/src/widgets/framework.dart:6442:14)
#398 Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#399 ComponentElement.performRebuild
(package:flutter/src/widgets/framework.dart:5111:16)
#400 Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7)
#401 ProxyElement.update (package:flutter/src/widgets/framework.dart:5417:5)
#402 Element.updateChild (package:flutter/src/widgets/framework.dart:3686:15)
#403 ComponentElement.performRebuild
(package:flutter/src/widgets/framework.dart:5111:16)
#404 StatefulElement.performRebuild
(package:flutter/src/widgets/framework.dart:5251:11)
#405 Element.rebuild (package:flutter/src/widgets/framework.dart:4805:7)
#406 BuildOwner.buildScope
(package:flutter/src/widgets/framework.dart:2780:19)
#407 WidgetsBinding.drawFrame
(package:flutter/src/widgets/binding.dart:903:21)
#408 RendererBinding._handlePersistentFrameCallback
(package:flutter/src/rendering/binding.dart:358:5)
#409 SchedulerBinding._invokeFrameCallback
(package:flutter/src/scheduler/binding.dart:1284:15)
#410 SchedulerBinding.handleDrawFrame
(package:flutter/src/scheduler/binding.dart:1214:9)
#411 SchedulerBinding._handleDrawFrame
(package:flutter/src/scheduler/binding.dart:1072:5)
#412 _invoke (dart:ui/hooks.dart:142:13)
#413 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:359:5)
#414 _drawFrame (dart:ui/hooks.dart:112:31)
════════════════════════════════════════════════════════════════════════════════
════════════════════
Another exception was thrown: Each child must be laid out exactly once.
Another exception was thrown: Updated layout information required for
RenderErrorBox#5cb32 NEEDS-LAYOUT NEEDS-PAINT to calculate semantics.
字符串
我的编码:
main.dart:
void main() {
runApp(DevicePreview(
enabled: !kReleaseMode,
builder: (context) => MultiProvider(
providers: [
RepositoryProvider(
create: (context) => AuthRepository(),
),
ChangeNotifierProvider(
create: (_) => ThemeProvider(),
),
ChangeNotifierProvider(
create: (_) => OCRImageProvider(),
),
BlocProvider(
create: (context) => PageBloc(),
),
BlocProvider(
create: (context) => JWTBloc(),
),
BlocProvider(
create: (context) => FileBloc(),
),
BlocProvider(
create: (context) => FilesBloc(),
),
BlocProvider(
create: (context) => ProfileBloc(),
),
BlocProvider(
create: (context) => AccessMethodBloc(),
),
BlocProvider(
create: (context) => ArticleBloc(),
),
BlocProvider(
create: (context) => PasswordBloc(),
),
BlocProvider(
create: (context) => LoginBloc(authRepo: context.read<AuthRepository>(), authCubit: AuthCubit(sessionCubit: SessionCubit(authRepo: AuthRepository())))
),
BlocProvider(
create: (context) => SignUpBloc(authRepo: context.read<AuthRepository>(), authCubit: context.read<AuthCubit>())
),
BlocProvider(
create: (context) => PasswordBloc(),
),
BlocProvider(
create: (context) => OnlineBloc(),
),
BlocProvider(
create: (context)
=> SessionCubit(authRepo: context.read<AuthRepository>(),),
child: AppNavigator(), //responsible for showing the view
),
],
child: const MyApp(),
)));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
final themeProvider = Provider.of<ThemeProvider>(context);
return
// RepositoryProvider(
// create: (context) => AuthRepository(),
// child:
MaterialApp(
locale: DevicePreview.locale(context),
builder: DevicePreview.appBuilder,
title: 'Study-Savvy',
theme: LightStyle.theme,
darkTheme: DarkStyle.theme,
themeMode: themeProvider.themeMode,
//initialRoute: Routes.home,
onGenerateRoute: RouteGenerator.generateRoute,
debugShowCheckedModeBanner: false,
home: Container(
alignment: Alignment.center,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/initial.jpg'),
fit: BoxFit.cover,
)),
child: const HomePage(),
)
//)
);
}
}
型
sign_up.dart:
class SignUpView extends StatelessWidget {
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Scaffold(
// body: BlocProvider(
// create: (context) => SignUpBloc(
// authRepo: context.read<AuthRepository>(),
// authCubit: context.read<AuthCubit>(),
// ),
//child:
body:
Stack(
alignment: Alignment.bottomCenter,
children: [
_signUpForm(),
_showLoginButton(context),
],
),
//),
);
}
Widget _signUpForm() {
return BlocListener<SignUpBloc, SignUpState>(
listener: (context, state) {
final formStatus = state.formStatus;
if (formStatus is SubmissionFailed) {
_showSnackBar(context, formStatus.exception.toString());
}
},
child: Form(
key: _formKey,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 40),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_usernameField(),
_emailField(),
_passwordField(),
_signUpButton(),
],
),
),
));
}
Widget _usernameField() {
return BlocBuilder<SignUpBloc, SignUpState>(builder: (context, state) {
return TextFormField(
decoration: InputDecoration(
icon: Icon(Icons.person),
hintText: 'Username',
),
validator: (value) =>
state.isValidUsername ? null : 'Username is too short',
onChanged: (value) => context.read<SignUpBloc>().add(
SignUpUsernameChanged(username: value),
),
);
});
}
Widget _emailField() {
return BlocBuilder<SignUpBloc, SignUpState>(builder: (context, state) {
return TextFormField(
decoration: InputDecoration(
icon: Icon(Icons.person),
hintText: 'Email',
),
validator: (value) => state.isValidUsername ? null : 'Invalid email',
onChanged: (value) => context.read<SignUpBloc>().add(
SignUpEmailChanged(email: value),
),
);
});
}
Widget _passwordField() {
return BlocBuilder<SignUpBloc, SignUpState>(builder: (context, state) {
return TextFormField(
obscureText: true,
decoration: InputDecoration(
icon: Icon(Icons.security),
hintText: 'Password',
),
validator: (value) =>
state.isValidPassword ? null : 'Password is too short',
onChanged: (value) => context.read<SignUpBloc>().add(
SignUpPasswordChanged(password: value),
),
);
});
}
Widget _signUpButton() {
return BlocBuilder<SignUpBloc, SignUpState>(builder: (context, state) {
return state.formStatus is FormSubmitting
? CircularProgressIndicator()
: ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
context.read<SignUpBloc>().add(SignUpSubmitted());
}
},
child: Text('Sign Up'),
);
});
}
Widget _showLoginButton(BuildContext context) {
return SafeArea(
child: TextButton(
child: Text('Already have an account? Sign in.'),
onPressed: () => context.read<AuthCubit>().showLogin(),
),
);
}
void _showSnackBar(BuildContext context, String message) {
final snackBar = SnackBar(content: Text(message));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
}
型
注册_bloc.dart:
class SignUpBloc extends Bloc<SignUpEvent, SignUpState> {
final AuthRepository authRepo;
final AuthCubit authCubit;
SignUpBloc({required this.authRepo, required this.authCubit})
: super(SignUpState()){
on<SignUpEvent>(_onEvent);
}
Future<void> _onEvent(SignUpEvent event, Emitter<SignUpState> emit) async {
// Username updated
if (event is SignUpUsernameChanged) {
emit(state.copyWith(username: event.username));
// Email updated
} else if (event is SignUpEmailChanged) {
emit(state.copyWith(email: event.email));
// Password updated
} else if (event is SignUpPasswordChanged) {
emit(state.copyWith(password: event.password));
// Form submitted
} else if (event is SignUpSubmitted) {
emit(state.copyWith(formStatus: FormSubmitting()));
try {
await authRepo.signUp(
username: state.username,
email: state.email,
password: state.password,
);
emit(state.copyWith(formStatus: SubmissionSuccess()));
authCubit.showConfirmSignUp(
username: state.username,
email: state.email,
password: state.password,
);
} catch (e) {
emit(state.copyWith(formStatus: SubmissionFailed(e.toString() as Exception)));
}
}
}
}
型
auth_cubit:
enum AuthState { login, signUp, confirmSignUp }
class AuthCubit extends Cubit<AuthState> {
final SessionCubit sessionCubit;
AuthCubit({required this.sessionCubit}) : super(AuthState.login);
late AuthCredentials credentials;
void showLogin() => emit(AuthState.login);
void showSignUp() => emit(AuthState.signUp);
void showConfirmSignUp({
required String username,
required String email,
required String password,
}) {
credentials = AuthCredentials( //crate right here, to hand on argument
username: username,
email: email,
password: password,
);
emit(AuthState.confirmSignUp); //show confirm view
}
void launchSession(AuthCredentials credentials) =>
sessionCubit.showSession(credentials);
}
型
auth_navigator.dart:
class AuthNavigator extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<AuthCubit, AuthState>(builder: (context, state) {
return Navigator(
pages: [
// Show login
if (state == AuthState.login) MaterialPage(child: SignInPage()),
// Allow push animation
if (state == AuthState.signUp ||
state == AuthState.confirmSignUp) ...[
// Show Sign up
MaterialPage(child: SignUpView()),
// Show confirm sign up
if (state == AuthState.confirmSignUp)
MaterialPage(child: ConfirmationView())
]
],
onPopPage: (route, result) => route.didPop(result),
);
});
}
}
型
session_cubit.dart:
class SessionCubit extends Cubit<SessionState> {
final AuthRepository authRepo;
SessionCubit({required this.authRepo}) : super(UnknownSessionState()) {
attemptAutoLogin();
}
void attemptAutoLogin() async {
try {
final userId = await authRepo.attemptAutoLogin();
// final user = dataRepo.getUser(userId);
final user = userId;
emit(Authenticated(user: user));
} on Exception {
emit(Unauthenticated());
}
}
void showAuth() => emit(Unauthenticated());
void showSession(AuthCredentials credentials) {
// final user = dataRepo.getUser(credentials.userId);
final user = credentials.username;
emit(Authenticated(user: user));
}
void signOut() {
authRepo.signOut();
emit(Unauthenticated());
}
}
型
app_navigator.dart:
class AppNavigator extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<SessionCubit, SessionState>(builder: (context, state) {
return Navigator(
pages: [
// Show loading screen
if (state is UnknownSessionState) MaterialPage(child: LoadingView()),
// Show auth flow
if (state is Unauthenticated)
MaterialPage(
child: BlocProvider(
create: (context) =>
AuthCubit(sessionCubit: context.read<SessionCubit>()),
child: AuthNavigator(),
),
),
// Show session flow
if (state is Authenticated) MaterialPage(child: HomePage())
],
onPopPage: (route, result) => route.didPop(result),
);
});
}
}
型
我按照YouTube上的教程一步一步地(video),并改变了一些细节。例如,我有Initial.dart来导航到一开始的登录/注册页面。
当我选择登录按钮时,应用程序可以正常运行,并进入我的以下页面。
但是,当我点击“注册”按钮时,无论在哪个页面,屏幕都是空的,并发生错误。
谢谢你!!!:))
1条答案
按热度按时间svgewumm1#
从
auth Navigator
页面移动到sign up
页面你必须提供
auth cubit
到sign up
页.在这里
字符串
使用
BlocProvider.value
并将auth cubit的值提供给signup
页面用这个代替,
型
然后它会工作。