8

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.

2
  • I fail to see what you do not understand if you're coming from Vue/React. Reusing style in Flutter is like scoped styled in Vue or the package styled-component in React. Commented Sep 14, 2019 at 22:13
  • I don't see how scoped style enhances reusability of styles. Also i editet my post, to make my question more clear. Commented Sep 15, 2019 at 7:41

1 Answer 1

1

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'),
  ),
)
Sign up to request clarification or add additional context in comments.

3 Comments

Thats what I thought of too. The downside of this approach is, that it leads to a lot of nesting, which is one of the few things i don't like about flutter. How ever, thats probably just the flutter way of doing things. Thanks for your answer!
Well, you can make yet another stateless widget that combines multiple of these reusable widgets to reduce the nesting. That's what Container does.
I feel like I had this all in mind but thought it was the wrong way, thanks for clarifying. I should break out of my css-like thinking.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.