Глобальные переменные в дротике
Я пытаюсь создать одностраничное приложение Dart.
Я создал первый пользовательский элемент (custom-application
) который содержит все приложение. В нем есть контейнер, который используется для визуализации представлений. И боковая навигация, которая будет содержать информацию о пользователе и обновляться при входе пользователя в систему.
Я хочу поделиться информацией между взглядами. Как я могу определить глобальную переменную в custom-application
и сможете поделиться этим с другими взглядами?
Например, когда вы запускаете приложение, вы не проходите аутентификацию. Когда вы звоните / логин (login-view
) у вас будет форма входа. Я хочу, чтобы при входе в приложение custom-application
элемент хранит пользовательскую информацию, загруженную вложенным представлением login-view
и обновить боковую навигацию.
Возможно ли это сделать?
7 ответов
Просто создайте файл библиотеки и создайте поля для глобалов, которые вам нужны. Импортируйте эту библиотеку везде, где вам нужен доступ к этим полям.
app.dart
import 'globals.dart' as globals;
main() {
globals.isLoggedIn = true;
}
component1.dart
import 'globals.dart' as globals;
class MyComponent {
view() {
if(globals.isLoggedIn) {
doSomething();
else {
doSomethingElse();
}
}
}
globals.dart
library my_prj.globals;
bool isLoggedIn = false;
Вы также можете
- создать синглтон в библиотеке глобалов (подробнее см. Как построить синглтон в дротике?).
- используйте observable для получения уведомлений об изменениях (см. " Реализация шаблона Observer в Dart", " Как я могу инициировать своего рода событие onChange в классе для более подробной информации)"
Вы можете создать класс
myColors.dart
class AppColors {
static var primary = Colors.blue;
}
И импорт вашего класса
import 'package:myapp/.../myColors.dart';
И доступ с AppColors.primary
Я создал файл dart, который назвал my-globals.dart, в котором я могу определить свои глобальные переменные.
Так:
library globals;
int globalInt = 0;
bool globalBoolean = true;
String globalString = "";
double globalDouble= 10.0;
Это весь файл дротика.
А затем в том же каталоге или папке я могу создавать другие классы, где я могу получить доступ к своим глобальным объектам, импортировав my-globals.dart как глобальные объекты. Давайте создадим класс, расширяющий StatefulWidget. Здесь мы собираемся изменить значение глобальной переменной globalInt, нажав Flatbutton.
import 'package:flutter/material.dart';
import 'my-globals.dart' as globals;
class OtherClass extends StatefulWidget {
OtherClass({Key key}) : super(key: key);
@override
_OtherClassState createState() => _OtherClassState();
}
class _OtherClassState extends State<OtherClass> {
@override
Widget build(BuildContext context) {
return Container(
child: FlatButton(
color: Colors.blue,
textColor: Colors.white,
onPressed: () {
setState(() {globals.globalInt++;});
print(globals.globalInt);
},
),
);
}
}
Понимаете. Я просто получил доступ к переменной, которую хотел, написав глобальные переменные. а затем имя переменной, содержащейся в библиотеке.
Надеюсь, этот пример поможет лучше понять, как использовать библиотеку глобальных объектов.
У меня была такая же проблема с глобальными переменными. Поэтому мне также требовались разные конфигурации для каждой версии приложения (dev / prod), и я не хочу записывать конфигурацию в файл main_dev.dart или main_prod.dart.
Я написал простой пакет флаттера, который имеет дело с разделением файлов конфигурации и загрузкой их при запуске приложения. Конфигурация будет доступна в каждой строке кода в вашем приложении.
https://github.com/Ephenodrom/Flutter-Global-Config
Как это использовать:
Создайте файл json в assets/cfg/$file.json
Добавьте assets / cfg в ваш pubspec.yaml
Загрузка различных файлов конфигурации при запуске приложения:
import 'package:flutter/material.dart';
import 'package:global_configuration/global_configuration.dart';
void main() async{
await GlobalConfiguration().loadFromAsset("app_settings");
await GlobalConfiguration().loadFromAsset("env_dev_settings");
runApp(MyApp());
}
class MyApp extends StatelessWidget {
...
}
Используя конфигурацию в вашем приложении:
import 'package:flutter/material.dart';
import 'package:global_configuration/global_configuration.dart';
class CustomWidget extends StatelessWidget {
CustomWiget(){
// Access the config in the constructor
print(GlobalConfiguration().getString("key1"); // prints value1
}
@override
Widget build(BuildContext context) {
// Access the config in the build method
return new Text(GlobalConfiguration().getString("key2"));
}
}
Все, что вам нужно, это создать файл типа "constatnts.dart".
import '...materials.dart';
const Color baseColor = Color(0XFF353535);
и использовать вот так
import '...constants.dart';
.......
......
....
Container(
color: baseColor,
.....
),
Основываясь на идее библиотеки, здесь есть способ добавить "ключевые" глобальные переменные любого типа к карте, вызываемой из других виджетов. Таким образом, вам не нужно заранее объявлять такие переменные. Если переменная не существует, она добавляется на карту с помощью appDataSet. Таким образом, в такой виджет, как флажок, вы можете добавить, например, в функцию setState(): appDataSet('aCheckBox',value); Если aCheckBox не существует на карте, он добавляется, и значение загружается со значением (в данном случае логическим).
library my_prj.globals;
Map appData = Map<String,dynamic>();
void appDataSet(String key, dynamic value) {
if (!appData.containsKey(key))
appData.putIfAbsent(key, () => value);
else
appData.update(key, (dynamic) => value);
print(appData);
}
dynamic appDataGet(String key) {
if (appData.containsKey(key))
return (appData.putIfAbsent(key, () => {}));
else
return (null);
}
Глобальные переменные обычно осуждаются. Рекомендуемое решение для флаттера — библиотека провайдера. Это просто виджет, который вы вставляете где-то высоко в дереве виджетов и даете ему какое-то значение (объект, класс) для хранения. Затем вы получаете доступ к значению глубже внутри других виджетов.
В отличие от глобальной переменной, вы можете изменить значение, хранящееся в провайдере, и виджеты глубоко внутри будут повторно отображаться.
Значение магазина
Widget build(BuildContext context) {
String someValue = '5';
return Provider(
create: (_) => someValue),
child: SafeArea(...)
);
}
Получить значение:
@override
void initState() {
super.initState();
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
setState(() {
value5 = context.read<String>();
});
});
}