Flutter. Упрощаем компоновку виджетов с помощью Dart расширений

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

image


В версии Dart 2.7 нам представили расширения, позволяющие разработчикам добавлять новые функциональные возможности в уже существующие типы. Расширения могут быть отличным помощником не только, когда мы пишем бизнес-логику, но и когда у нас есть другие задачи! Примером такой задачи может служить работа с виджетами.


Исходя из своего опыта разработки под iOS, вдохновившись ViewModifier из SwiftUI, я захотел разобраться в том, как использовать Dart расширения аналогичным образом, чтобы уменьшить визуальный беспорядок, который получается при большой вложенности дерева виджетов.


Давайте рассмотрим пример!


Вариант с вложенными виджетам


Ниже представлен MyWidget виджет c текстом внутри Padding (из стандартного примера с dartpad.dev).


class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return
      Padding(
        padding: const EdgeInsets.all(16),
        child: Text('Hello, World!', style: Theme.of(context).textTheme.headline4)
      );
  }
}

Теперь давайте разберёмся, как мы можем сделать то же самое с помощью Dart расширений.


Вариант с раширениями


Создаем расширение для класса Widget c методом padding. При вызове данного метода объект будет обернут в Padding:


extension WidgetModifier on Widget {
  Widget padding([EdgeInsetsGeometry value = const EdgeInsets.all(16)]) {
    return Padding(
      padding: value,
      child: this,
    );
  }
}

С новым расширением мы можем обновить MyWidget следующим образом:


class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text('Hello, World!', style: Theme.of(context).textTheme.headline4)
            .padding();
  }
}

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


Точно так же мы можем добавить в наше расширение еще функции и с их помощью создать более сложные пользовательские интерфейсы:


extension WidgetModifier on Widget {

  // ...

  Widget background(Color color) { // заливка
    return DecoratedBox(
      decoration: BoxDecoration(
        color: color,
      ),
      child: this,
    );
  }

  Widget cornerRadius(BorderRadiusGeometry radius) { // закругление углов
    return ClipRRect(
      borderRadius: radius,
      child: this,
    );
  }

  Widget align([AlignmentGeometry alignment = Alignment.center]) { // выравнивание
    return Align(
      alignment: alignment,
      child: this,
    );
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text('Hello, World!', style: Theme.of(context).textTheme.headline4)
            .padding()
            .background(Colors.lightBlue)
            .cornerRadius(BorderRadius.all(Radius.circular(8.0)))
            .padding(EdgeInsets.symmetric(horizontal: 8, vertical: 16))
            .background(Colors.purple);
  }
}


Посмотреть на dartpad.dev

Разве это не прекрасно? Теперь у нас есть чистый и элегантный виджет, который мы можем легко понять! Представьте себе, сколько уровней вложенных виджетов вам придется использовать, чтобы воссоздать это представление без расширений.


Заключение


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


Спасибо за внимание! Надеюсь, что вы найдете этот пост полезным. Если у вас есть какие-либо вопросы или комментарии по поводу данного материала, не стесняйтесь обращаться ко мне в Twitter!


До следующего раза!

Источник: https://habr.com/ru/post/510106/


Интересные статьи

Интересные статьи

Остановка нефтегазовых заводов — это миллионы долларов убытков. К сожалению, остановка обычно неизбежна, поскольку существует большое количество технологического оборудования и инструмент...
Сеть является основой для распределенных приложений. Распределенное приложение имеет несколько микросервисов, каждый из которых работает в наборе Подов, часто расположенных на разных ...
Вряд ли вам захочется разбираться с обработкой изображений в графических редакторах, если вы знаете, как сделать это с помощью открытых библиотек для Python. Читат...
На данный момент существует два основных подхода к поиску уязвимостей в приложениях — статический и динамический анализ. У обоих подходов есть свои плюсы и минусы. Рынок приходит к тому, что ис...
В этой статье рассмотрим "Алгоритм X" Кнута и его применение для решения судоку. Прелесть алгоритма в том, что судоку при этом решается быстро без программирования каких-то продвинутых техник реш...