Доступ к ширине экрана вне контекста

#flutter #flutter-layout #toast #flutter-web

#flutter #flutter-макет #тост #flutter-web

Вопрос:

Я создаю класс для уведомлений, который находится вне контекста, используя bot_toast, который будет вызываться при ошибках API и тому подобном. Мне нужно оставить поле, соответствующее ширине экрана, но здесь у меня нет контекста. Я мог бы передать контекст, это не кажется лучшим вариантом.

Итак, я заканчиваю чем-то вроде этого

 Function CustomToast (message) {
  return BotToast.showAttachedWidget(
      attachedBuilder: (_) => Align(
        alignment: Alignment.topRight,
        child: Container(
          margin: new EdgeInsets.only(top: 25, right: 25.0),
          color: Colors.blue,
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Text(
              message,              
            ),
          ),
        ),
      ),
      duration: Duration(seconds: 20),
      target: Offset(520, 520));
}
  

Мне нужно установить правильный запас в процентах. Как мне получить доступ к ширине экрана здесь? возможно ли это без контекста? Любое предложение приветствуется, даже изменение библиотеки тостов

Ответ №1:

Возможно, модель уровня приложения. После того, как у вас есть контекст, вы можете установить разрешение экрана для последующего извлечения вычисленного процента. Я часто использую этот подход.

   class ScreenInfoViewModel {
  List<String> _setupCompleted = [];

  String appName;
  String packageName;
  String version;
  String buildNumber;
  double screenWidth;

  ScreenInfoViewModel() {
    init();
  }

  init() async {
    var packageInfo = await PackageInfo.fromPlatform();
    appName = packageInfo.appName;
    packageName = packageInfo.packageName;
    version = packageInfo.version;
    buildNumber = packageInfo.buildNumber;
  }

  bool _smallScreen = false;
  bool _mediumScreen = false;
  bool _largeScreen = false;

  void setScreenSize(double this.screenWidth, double diagonalInches) {
    _smallScreen = diagonalInches < 5.11;
    _mediumScreen = !_smallScreen amp;amp; diagonalInches <= 5.6;
    _largeScreen = diagonalInches > 5.6;
  }

  bool get isSmallScreen => _smallScreen;
  bool get isMediumScreen => _mediumScreen;
  bool get isLargeScreen => _largeScreen;

  String get screenSize {
    String size = 'S';
    if (_mediumScreen) size = 'M';
    if (_largeScreen) size = 'L';
    return size;
  }
}
  

Я использую это таким образом:

 class SetupScreenInfo extends HookWidget {
  // Use GetIt package to retrieve the model
  final ScreenInfoViewModel _s = locator(); 

  final _scaffoldKey = new GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {

    ///  This is the first 'context' with a MediaQuery, therefore,
    ///  this is the first opportunity to set these values.
    ///  widthPx and diagonalInches are from sized_context package.
    _s.setScreenSize(context.widthPx, context.diagonalInches);

    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (context == null) return;
      Navigator.pushReplacementNamed(context, splashRoute);
    });

    return SafeArea(
      child: Scaffold(
        key: _scaffoldKey,
        body: Material(color: Colors.yellow[300]),
      ),
    );
  }
}
  

Наконец, SetupScreenInfo — это мой первоначальный маршрут из моего приложения MaterialApp.

Этот код является правкой моего производственного кода, он не тестировался и не является примером для выполнения.

Надеюсь, это поможет немного подумать.