Глобальные переменные в дротике

Я пытаюсь создать одностраничное приложение 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);
}

Глобальные переменные обычно осуждаются. Рекомендуемое решение для флаттера — библиотека провайдера. Это просто виджет, который вы вставляете где-то высоко в дереве виджетов и даете ему какое-то значение (объект, класс) для хранения. Затем вы получаете доступ к значению глубже внутри других виджетов.

В отличие от глобальной переменной, вы можете изменить значение, хранящееся в провайдере, и виджеты глубоко внутри будут повторно отображаться.

pub.dev/провайдер

Значение магазина

        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>();
      });
    });
  }
Другие вопросы по тегам