Как стать автором
Обновить

Комментарии 6

Для тех, кто не хочет тащить лишнюю зависимость, аналогичное можно реализовать парой виджетов. Бонусом будет легче под себя похачить (дополнить новыми комбинациями, поменять размеры и т.п.)


Код

responsive_builder.dart


import 'package:flutter/material.dart';

class ResponsiveBuilder extends StatelessWidget {
  final Widget Function(
      BuildContext context, SizingInformation sizingInformation) builder;
  const ResponsiveBuilder({Key key, this.builder}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    var sizingInformation = SizingInformation();
    return builder(context, sizingInformation);
  }
}

class SizingInformation {
  final DeviceScreenType deviceScreenType;
  final Size screenSize;
  final Size localWidgetSize;

  SizingInformation({
    this.deviceScreenType,
    this.screenSize,
    this.localWidgetSize,
  });

  @override
  String toString() {
    return 'DeviceType:$deviceScreenType ScreenSize:$screenSize LocalWidgetSize:$localWidgetSize';
  }
}

enum DeviceScreenType {
  Mobile,
  Tablet,
  Desktop
}

DeviceScreenType getDeviceType(MediaQueryData mediaQuery) {
  double deviceWidth = mediaQuery.size.shortestSide;

  if (deviceWidth > 950) {
    return DeviceScreenType.Desktop;
  }

  if (deviceWidth > 600) {
    return DeviceScreenType.Tablet;
  }

  return DeviceScreenType.Mobile;
}

screen_type_layout.dart


import 'package:flutter/material.dart';
import 'responsive_builder.dart';

class ScreenTypeLayout extends StatelessWidget {
  // Mobile will be returned by default
  final Widget mobile;
  final Widget tablet;
  final Widget desktop;

  const ScreenTypeLayout(
      {Key key, @required this.mobile, this.tablet, this.desktop})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ResponsiveBuilder(builder: (context, sizingInformation) {
      // If sizing indicates Tablet and we have a tablet widget then return
      if (sizingInformation.deviceScreenType == DeviceScreenType.Tablet) {
        if (tablet != null) {
          return tablet;
        }
      }

      // If sizing indicates desktop and we have a desktop widget then return
      if (sizingInformation.deviceScreenType == DeviceScreenType.Desktop) {
        if (desktop != null) {
          return desktop;
        }
      }

      // Return mobile layout if nothing else is supplied
      return mobile;
    });
  }
}

И пример использования:


import 'package:foo/widgets/layout/orientation_layout.dart';
import 'package:foo/widgets/layout/screen_type_layout.dart';
...
  @override
  Widget build(BuildContext context) {
    return  ScreenTypeLayout(
      mobile: OrientationLayout(
          portrait: ChatsScreen(),
          landscape: ChatsScreenWide()
      ),
      tablet: ChatsScreenWide(),
    );
  }
Я хотел бы написать ишьюс на GitHub, но там нельзя, поэтому здесь:
  1. В статье говориться о разрешении экрана (devicePixelRatio), но используются размеры экрана (size)
  2. Ваша пакет тенет за собой другой и как я понимаю ненужный ему пакет smooth_page_indicator (видно тут)
  3. Для названий файлов принято использовать snake case
  4. Если передавать кучу виджетов, но строить только 1, то это куча ненужной работы
      final Widget landscapeLargeScreen;
      final Widget landscapeMediumScreen;
      final Widget landscapeSmallScreen;
      final Widget portraitLargeScreen;
      final Widget portraitMediumScreen;
      final Widget portraitSmallScreen;

    Используйте WidgetBuilder
  5. Для того, что бы инициализировать ваш класс (SizerUtil), нужны странные манипуляции. Например, OrientationBuilder основан на LayoutBuilder, но просто предлагает другой билдер в итоге имеется 2 вложения которые не нужны (не то, что бы от этого сильно измениться что-то, но там немного, здесь немного и уже лагает всё)
  6. Использовать статический класс для значений которые могут измениться и нужно будет перестраивать дерево — плохо. Посмотрите на реализацию MediaQuery
  7. В вашем примере есть такой код:
    body: ResponsiveWidget(
     landscapeLargeScreen: WelcomePage(
       pageIndex: 0,
       scrollDirection: Axis.vertical,
       children: listOfPages,
     ),
     portraitLargeScreen: WelcomePage(
       pageIndex: 0,
       scrollDirection: Axis.horizontal,
       children: listOfPages,
     ),
    ),

    Который отличается 1 параметром — это ещё один повод задуматься над удобным API и пунктом 4 из этого списка
Спасибо за замечание, учту. И заодно включил issues

Так в Flutter 2, который недавно вышел уже нормальная поддержка веб-приложений. Not a beta channel. Или я не прав?

точно. поправил. Спасибо. У меня просто включен beta-channel так что я особо и не заметил это событие )
Зарегистрируйтесь на Хабре , чтобы оставить комментарий