[英]How to change state of cubit?
當我單擊按鈕時,我想在 4 秒后更改 state 的肘,但它給出了錯誤:
**BlocProvider.of() called with a context that does not contain a TestCubit.
======== Exception caught by gesture ===============================================================
The following assertion was thrown while handling a gesture:
BlocProvider.of() called with a context that does not contain a TestCubit.
No ancestor could be found starting from the context that was passed to BlocProvider.of<TestCubit>().
This can happen if the context you used comes from a widget above the BlocProvider.
The context used was: MyHomePage(state: _MyHomePageState#ea89e)
When the exception was thrown, this was the stack:
#0 BlocProvider.of (package:flutter_bloc/src/bloc_provider.dart:103:7)
#1 _MyHomePageState.build.<anonymous closure> (package:flutter_cubit/main.dart:58:34)
#2 _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1072:21)
#3 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:253:24)
#4 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:627:11)
#5 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:306:5)
#6 BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:239:7)
#7 PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:615:9)
#8 PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
#9 PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
#10 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
#11 PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
#12 PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
#13 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:460:19)
#14 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:440:22)
#15 RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:337:11)
#16 GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:395:7)
#17 GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:357:5)
#18 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:314:7)
#19 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:295:7)
#20 _invoke1 (dart:ui/hooks.dart:167:13)
#21 PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:341:7)
#22 _dispatchPointerDataPacket (dart:ui/hooks.dart:94:31)
Handler: "onTap"
Recognizer: TapGestureRecognizer#97fe2
debugOwner: GestureDetector
state: possible
won arena
finalPosition: Offset(188.3, 443.5)
finalLocalPosition: Offset(30.8, 20.5)
button: 1
sent tap down**
我的代碼在這里:
主要.dart
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_cubit/bloc/test_cubit.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Cubit Bloc'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
BlocProvider(
create: (_) => TestCubit(),
child: BlocBuilder<TestCubit, TestState>(
builder: (context, state) {
if (state is Loading) {
return CircularProgressIndicator();
} else
if (state is Loaded) {
return Text('Loaded');
}
return Text('Error');
},
),
),
ElevatedButton(
onPressed: () {
BlocProvider.of<TestCubit>(context).getData();
},
child: Text('Click')
)
],
)
)
);
}
}
手肘
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
part 'test_state.dart';
class TestCubit extends Cubit<TestState> {
TestCubit() : super(Loading());
Future<void> getData() async {
try {
emit(Loading());
await Future.delayed(Duration(seconds: 4));
emit(Loaded());
} catch (e) {
emit(ErrorException());
}
}
}
測試狀態
part of 'test_cubit.dart';
abstract class TestState extends Equatable {
const TestState();
}
class Loading extends TestState {
const Loading();
@override
// TODO: implement props
List<Object?> get props => throw UnimplementedError();
}
class Loaded extends TestState {
const Loaded();
@override
// TODO: implement props
List<Object?> get props => throw UnimplementedError();
}
class ErrorException extends TestState {
const ErrorException();
@override
// TODO: implement props
List<Object?> get props => throw UnimplementedError();
}
您在錯誤的 scope 中使用了 BlocProvider,請嘗試將 BlocProvider 移出 MyHomePage class
試試這個:
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_cubit/bloc/test_cubit.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => TestCubit(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Cubit Bloc'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
BlocBuilder<TestCubit, TestState>(
builder: (context, state) {
if (state is Loading) {
return CircularProgressIndicator();
} else if (state is Loaded) {
return Text('Loaded');
}
return Text('Error');
},
),
ElevatedButton(
onPressed: () {
BlocProvider.of<TestCubit>(context).getData();
},
child: Text('Click')
)
],
)
)
);
}
}
你有兩種方法可以做到這一點。 首先請記住, BlocProvider.of
只會找到小部件樹頂部的 bloc object。 您將TestBloc()
放在對等小部件中。 您附加的小部件TestBloc()
應該覆蓋您使用BlocProvider.of的地方
**重要:**但我更喜歡另一種方式,因為它很容易理解
聲明var testBloc=TestBloc();
在 widgetState class 內部的構建方法之外。然后使用testBloc.someMethod
BlocProvider.of
不要忘記把它也放在這里:
BlocProvider(
create: (_) => testCubit,
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.