我正在看一个教程,很明显,BLoc不适用于匿名路由,因为它们显然不共享上下文。但是,我的简单应用程序可以使用匿名路由。
这是一个简单的计数器应用程序,有2个屏幕,用户可以在两个屏幕上操作计数器。在教程中,当他运行这个应用程序并导航到第二个屏幕时,应用程序崩溃,但我的没有,并且工作正常。
下面是代码:
main.dart:
import 'package:counter_bloc_test/logic/cubits/counter_cubit.dart';
import 'package:counter_bloc_test/frontend/screens/home_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return BlocProvider<CounterCubit>(
create: (context) => CounterCubit(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const HomeScreen(title: 'Flutter Demo Home Page', color: Colors.blue,),
),
);
}
}
homescreen.dart:
import 'package:flutter/material.dart';
import 'package:counter_bloc_test/logic/cubits/counter_cubit.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:counter_bloc_test/frontend/screens/second_screen.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key, required this.title , required this.color});
final String title;
final Color color;
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
BlocConsumer<CounterCubit, CounterState>(
listener: (context, state) {
if(state.wasIncremented){
ScaffoldMessenger.of(context).removeCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("Incremented"),
)
);
}else{
ScaffoldMessenger.of(context).removeCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("Decremented"),
)
);
}
},
builder: (context, state) {
return Text(
state.counterValue.toString(),
style: Theme.of(context).textTheme.headlineMedium,
);
},
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
FloatingActionButton(
heroTag: "btn1",
onPressed: () {
BlocProvider.of<CounterCubit>(context).decrement();
},
tooltip: 'Decrement',
child: const Icon(Icons.remove),
),
FloatingActionButton(
heroTag: "btn2",
onPressed: () {
BlocProvider.of<CounterCubit>(context).increment();
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
],
),
const SizedBox(height: 24,),
MaterialButton(
color: widget.color,
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const SecondScreen(
title: "Second Screen",
color: Colors.redAccent,
)
)
);
},
child: const Text('Go to Second Page'),
)
],
),
),
);
}
}
second_screen.dart
import 'package:flutter/material.dart';
import 'package:counter_bloc_test/logic/cubits/counter_cubit.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class SecondScreen extends StatefulWidget {
const SecondScreen({super.key, required this.title , required this.color});
final String title;
final Color color;
@override
State<SecondScreen> createState() => _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.redAccent,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
BlocConsumer<CounterCubit, CounterState>(
listener: (context, state) {
if(state.wasIncremented){
ScaffoldMessenger.of(context).removeCurrentMaterialBanner();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("Incremented"),
)
);
}else{
ScaffoldMessenger.of(context).removeCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("Decremented"),
)
);
}
},
builder: (context, state) {
return Text(
state.counterValue.toString(),
style: Theme.of(context).textTheme.headlineMedium,
);
},
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
FloatingActionButton(
heroTag: null,
onPressed: () {
BlocProvider.of<CounterCubit>(context).decrement();
},
tooltip: 'Decrement',
child: const Icon(Icons.remove),
),
FloatingActionButton(
heroTag: null,
onPressed: () {
BlocProvider.of<CounterCubit>(context).increment();
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
],
),
const SizedBox(height: 24,),
MaterialButton(
color: widget.color,
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('Go to First Page'),
)
],
),
),
);
}
}
我预计应用程序会引发错误,但状态被保留,它工作正常。我正在使用BLOCK 8.1和Flutter 3.10
2条答案
按热度按时间xzlaal3s1#
区别在于您使用的初始提供程序。通过用
BlocProvider
PackageMaterialApp
,您可以使其在整个应用程序中全局可用。如果提供程序位于您的
HomeScreen
中,您预期会出现错误,这是正确的。nlejzf6q2#
这段代码之所以有效,是因为BlocProvider包裹在我的素材应用程序周围,因此它在全球范围内可用。我所遵循的教程有应用程序崩溃,因为他后来更改了代码,以 Package 主屏幕,以便我们可以看到错误。他没有宣布他正在改变代码我还在 Package 材料应用程序。谢谢