In Dart 2.7, we were introduced to extensions that allow developers to add new functionality to existing types. Extensions can be a great helper not only when we write business logic, but also when we have other tasks! An example of such a task is working with widgets.
Based on my experience in iOS development, inspired by ViewModifier
SwiftUI, I wanted to figure out how to use Dart extensions in a similar way to reduce the visual clutter that results from a large nesting of the widget tree.
Let's take an example!
Option with nested widgets
Below is a MyWidget
widget with text inside Padding
(from the standard example with 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)
);
}
}
Now let's see how we can do the same with Dart extensions.
Option with extensions
We create an extension for the class Widget
with the method padding
. When this method is called, the object will be wrapped in Padding
:
extension WidgetModifier on Widget {
Widget padding([EdgeInsetsGeometry value = const EdgeInsets.all(16)]) {
return Padding(
padding: value,
child: this,
);
}
}
With the new extension, we can update MyWidget
as follows:
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
? , ! , , .
In this article, we considered an alternative approach to forming a tree of widgets in a Flutter project, using a concept similar to that ViewModifier
from SwiftUI. With this approach, we can simplify the widget trees by reducing their nesting. And I have demonstrated only a few examples of such extensions, but by the same principle, you can create many new ones for other cases where they will be just as useful.
Thanks for your attention! Hope you find this post helpful. If you have any questions or comments about this material, feel free to contact me on Twitter !
Until next time!