Этого можно добиться, используя свойство builder
MaterialApp
.
lib / main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class SomeBloc {
final String someValue;
SomeBloc(this.someValue);
void dispose() {}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
SomeBloc _someBloc = SomeBloc("someValue");
@override
Widget build(BuildContext context) {
return MaterialApp(
builder: (context, widget) => Provider<SomeBloc>(
create: (_) => _someBloc,
dispose: (_, bloc) => bloc.dispose(),
child: widget,
),
initialRoute: '/first-page',
routes: <String, WidgetBuilder>{
'/first-page': (context) => FirstPage(),
'/second-page': (context) => SecondPage(),
},
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
SomeBloc _someBloc = Provider.of<SomeBloc>(context);
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(_someBloc.someValue),
RaisedButton(
child: Text("Open second page"),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => SecondPage(),
),
),
)
],
),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
SomeBloc _someBloc = Provider.of<SomeBloc>(context);
return Scaffold(
body: Center(
child: Text(_someBloc.someValue),
),
);
}
}
Согласно документации,
home
Разница между использованием home и использованием builder заключается в том, что поддерево home вставляется в приложение ниже a Navigator.
builder
... виджет, возвращаемый из Builder, вставляется над навигатором приложения (если есть).
Если вы хотите, чтобы ваши «блоки» предоставлялись на всех ваших маршрутах, вы должны предоставить их выше виджета Navigator
.
Вот почему это просто работает:
return Provider(
create: (_) => _someBloc,
child: MaterialApp(
home: FirstPage(),
),
);
В приведенной выше настройке Provider
находится над виджетом Navigator
.
И это не так:
return MaterialApp(
home: Provider(
create: (_) => _someBloc,
child: FirstPage(),
),
);
_someBloc
будет доступен только для виджета FirstPage
.
Надеюсь, это поможет.