Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reuse widget styles properly in flutter?

Coming from frontend webframeworks like angular, react and vue I am struggling to find the best way to write reusable widget styles. Let me demonstrate the problem with an example.

Lets say we have this Widget:

Container(
  width: 25,
  height: 10,
  decoration: BoxDecoration(
    color: const Color(0xff7c94b6),
    border: Border.all(
      color: Colors.black,
      width: 8.0,
      ),
    ),
  child: /* some custom widget */,
);

Now lets say I want to make the Container properties like width, height etc. changable by parameters. If a certain parameter for a property is not passed it should use its default value, like this:

class CustomWidget extends StatelessWidget {
  final double width;
  final double height;
  final BoxDecoration decoration;

  const CustomWidget ({
    Key key,
    this.width = 25,
    this.height = 10,
    this.decoration = /* default decoration */
    /* possibly even more properties */
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: width,
      height: height,
      decoration: decoration,
      child: /* some custom widget */
  }
}

Obviously, there could be more properties which would lead to more and more boilerplate. Also what do you do, if the container does not have a decoration by default? Should you pass a custom Container always? Also consider that the Container could be nested further down the widget tree.

There must be a good solution, I just can't think of one, probably because my thoughts are biased because of my experience with frontend development. In web project you simply pass the component/widget custom css-classes to overwrite the styles (e.g. a parameter containerClasses). How do you do it properly in flutter?

EDIT: In essence my question is: Is there an equivalent to a css-class in flutter? Or: Whats the best way to make a custom widget's style totally customizable by parameters. I feel like i have to write every single property by hand.

In react you have an interface for all html elements (e.g. div, input etc.) and their props (e.g. for an input-element you have an interface with value, class, type etc.), which you can use to define what parameters one can pass to customize the component/widget.

like image 824
oemera Avatar asked Sep 14 '19 20:09

oemera


1 Answers

Flutter style behaves similarly to Vue scoped styled / React "styled-component" or React native in general:

There's no "global style" in these scenarios. Instead, you use composition to obtain the desired result.

In a sense, you have one StatelessWidget for each "CSS class", instead of one big StatelessWidget with many parameters.

For example, say we want to split a "red background + border radius" into reusable styles, then we'd typically have two widgets:

  • RedBackground
  • MyBorder

where you would then be able to use them independently:

RedBackground(
  child: Text('hello world'),
)

or together:

RedBackground(
  child: MyBorder(
    child: Text('hello world'),
  ),
)
like image 192
Rémi Rousselet Avatar answered Oct 14 '22 23:10

Rémi Rousselet