Я пытался создать приложение, используя флаттер, и мне трудно разобраться в некоторых концепциях флаттера. Я надеюсь найти здесь несколько ответов.
Предисловие: Зависимости приложения: flutter_mobx, auto_route, get_it .
Я создаю приложение, в котором мне нужно показать несколько предупреждений. , Я создал страницу флаттера (AlertsScreen
), на которую подписано mobx alerts_store . Поэтому всякий раз, когда я пытаюсь выдать sh предупреждение в alerts_store , должна появиться снэк-бар. Нечто похожее на то, что я делал в сети React.
Ссылка на репозиторий приложения: https://github.com/ganeshrvel/open_cloud_encryptor/tree/new-router-logic
Вопросы:
- Как это сделать Я монтирую общий виджет типа
AlertsScreen()
, который будет отображаться в приложении. Раньше я делал что-то вроде этого:
app.dart ( ссылка Github )
MaterialApp(
builder: (BuildContext context, Widget widget) {
setErrorBuilder();
return Column(
children: <Widget>[
Expanded(
child: widget,
),
AlertsScreen(),
],
);
},
title: 'App name',
onGenerateRoute: Router.onGenerateRoute,
initialRoute: Router.splashScreen,
navigatorKey: Router.navigator.key,
),
Но потом всякий раз, когда я пытаюсь отрендерить Flushbar или любой другой другой элемент внутри AlertsScreen, для которого требуется context
, выдает ошибку:
[ОШИБКА: flutter / lib / ui / ui_dart_state. cc (157)] Необработанное исключение: операция навигатора запрошена с контекстом это не включает в себя навигатор. Контекст, используемый для pu sh или поп-маршрутов из навигатора, должен соответствовать контексту виджета, являющегося потомком виджета навигатора.
Пример кода Flushbar:
Flushbar(title: 'title',message: 'body',duration: const Duration(seconds: 5),).show(context);
Как мне смонтировать общий виджет типа AlertsScreen
в приложении и который всегда будет виден для любого вида деятельности?
2) Этот ответ из stackoverflow предлагает создать CommonWidget виджет без состояния и используйте его везде, где он должен быть представлен. Поэтому, принимая подсказки из приведенного выше ответа stackoverflow, я изменил свой код следующим образом:
common_widget.dart ( Github link )
class CommonWidget extends StatelessWidget {
final Widget child;
const CommonWidget({
@required this.child,
});
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Expanded(
child: child,
),
AlertsScreen(),
],
);
}
}
home.dart ( Github link )
class _HomeScreenState extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home'),
),
body: CommonWidget(
child: Center(
child: Column(),
),
),
);
}
}
Это правильный способ сделать это?
3) Я использую flutter_mobx в качестве хранилища для AlertsScreen
. Поскольку я использовал CommonWidget на нескольких экранах для отображения AlertsScreen
, при каждом обновлении магазина AlertsScreen перестраивался несколько раз. Как мне это предотвратить? Как сделать так, чтобы виджет AlertsScreen
перерисовывался только на текущем экране, и предотвратить его восстановление во всех других местах при обновлении магазина?
Текущий обходной путь выглядит примерно так:
alerts .dart ( Github Link )
@override
void didChangeDependencies() {
super.didChangeDependencies();
_alertsStore ??= Provider.of<AlertsStore>(context);
_disposers ??= [
reaction(
(_) => _alertsStore.alertsList.iterator,
(alertsList) {
if (ModalRoute.of(context).isCurrent) { // Check whether current screen is rendered
buildSnackbar();
}
},
),
];
}
Есть ли лучший способ сделать это?