Dart: spread operator for constructor
Solution 1
You can do something like this:
const BorderSide borderBase = BorderSide(
color: Colors.red,
width: 2,
style: BorderStyle.solid,
);
Container(
decoration: BoxDecoration(
border: Border.all(
color: borderBase.color,
width: borderBase.width,
style: borderBase.style,
),
),
child: Text('Container 1'),
)
Container(
decoration: BoxDecoration(
border: Border(
top: borderBase,
),
),
child: Text('Container 2'),
)
Not the best but still some reuse.
Solution 2
There is no such thing.
A spread operator is in development, but it is only for lists, not classes (https://github.com/dart-lang/language/issues/47)
Solution 3
Now that dart has both the spread operator and class extensions, you could abuse both to add ...spread
support to static
methods. While I doubt this is a good idea, I made a working dartpad (gist) to demonstrate. The end result looks something like:
final Border spreadBorder = Border.fromSides([
...Border(
left: BorderSide(color: Colors.pink),
right: BorderSide(color: Colors.pinkAccent),
).sides,
...Border(
top: BorderSide(color: Colors.blue),
bottom: BorderSide(color: Colors.blueAccent),
).sides,
]).scale(5);
enum _Side { top, right, bottom, left }
extension SpreadBorder on Border {
Iterable<MapEntry<_Side, BorderSide>> get sides {
return () sync* {
if (top != BorderSide.none) {
yield MapEntry(_Side.top, top);
}
// ...other yields
}();
}
static Border fromSides(Iterable<MapEntry<_Side, BorderSide>> parts) {
BorderSide top, right, bottom, left;
for (final borderPart in parts) {
switch (borderPart.key) {
case _Side.top:
top = borderPart.value;
break;
// ... other cases
}
}
return Border(
top: top,
right: right,
bottom: bottom,
left: left,
);
}
}
Solution 4
Here is a dummy sample of my poor man's spread operator pattern:
I make a copy constructor for classes often re-created with slight modifications. It is extra work during definition, but it pays off at many locations when using these classes. The same pattern can be used on standard classes by subclassing -- just to connect to the specific question.
class Address {
final String street;
final String city;
final String state;
Address({this.street, this.city, this.state});
Address.copy(Address copy, {
String street,
String city,
String state,
}) : this (
street: street ?? copy.street,
city: city ?? copy.city,
state: state ?? copy.state,
);
}
class User {
final String firstName;
final String lastName;
final Address address;
final String email;
User({this.firstName, this.lastName, this.address, this.email});
User.copy(User copy, {
String firstName,
String lastName,
Address address,
String email,
}) : this (
firstName: firstName ?? copy.firstName,
lastName: lastName ?? copy.lastName,
address: address ?? copy.address,
email: email ?? copy.email,
);
}
void workWithUsers(User user) {
final userChangedEmail = User.copy(user, email: '[email protected]');
final userMovedToAnotherStreet = User.copy(user, address: Address.copy(user.address, street: 'Newstreet'));
}
Giraldi
Updated on December 09, 2022Comments
-
Giraldi over 1 year
In my flutter app, I have widgets like below:
Container( decoration: BoxDecoration( border: Border.all( color: Colors.red, width: 2, style: BorderStyle.solid, ), ), child: Text('Container 1'), )
Container( decoration: BoxDecoration( border: Border( top: BorderSide( color: Colors.red, width: 2, style: BorderStyle.solid, ), ), ), child: Text('Container 2'), )
Both use the same properties for their borders. So I was wondering if there's a spread-operator-like way of inserting the same properties for both widgets? Maybe like:
const borderBase = ( color: Colors.red, width: 2, style: BorderStyle.solid, ) Container( decoration: BoxDecoration( border: Border.all( ...borderBase, ), ), child: Text('Container 1'), ) Container( decoration: BoxDecoration( border: Border( top: BorderSide( ...borderBase, ), ), ), child: Text('Container 2'), )
-
Giraldi about 5 yearsI see. So ther's no way to re-use the same properties dynamically? Meaning I have to repeat them everytime?
-
Rémi Rousselet about 5 yearsYes, you're forced to. But you can discuss about it on the issue. I think this is an interesting feature too.
-
Giraldi about 5 yearsBut this way I get errors in the
borderBase
variable sayingUndefined name 'color'
, and other linter errors. -
Giraldi about 5 yearsOh, I think you meant the
borderBase
var should use theBorderSide()
class, right? Cause that seems to work.