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

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

Время на прочтение3 мин
Количество просмотров7.1K
Автор оригинала: Ioannis Diamantidis

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!


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

Теги:
Хабы:
Всего голосов 11: ↑10 и ↓1+10
Комментарии4

Публикации

Истории

Работа

Swift разработчик
19 вакансий
iOS разработчик
17 вакансий

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань