Share dimensions between widgets

拈花ヽ惹草 提交于 2019-12-24 16:42:34

问题


In Flutter we can use Themes to share colors and font styles. https://flutter.io/docs/cookbook/design/themes

Is there an existing best practice that we can use in a similar manner share values such as margins, paddings and widths or heights?

Preferably something that helps stick to the material design guidelines.


回答1:


Defining custom widgets

The easiest and probably most elegant approach is to define custom widgets, like a MyRaisedButton that internally uses the RaisedButton with the right dimensions.

class MyRaisedButton extends StatelessWidget {
  MyRaisedButton({
    this.child,
    this.onPressed,
  });

  final Widget child;
  final VoidCallback onPressed;

  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      padding: ...,
      onPressed: onPressed,
      child: child
    );
  }
}

This works surprisingly well in most cases. However, if you still want to keep your widgets flexible (being able to pass a lot of customization options to the constructor), your overall widget definition quickly gets very long, because you need to forward all the options to the RaisedButton. In that case, it makes sense to actually share the values throughout the app.

Actually sharing values throughout the app

Of course, this approach is possible too. Due to Flutter's openness, we can just look at how the Theme is implemented and copy that code to create a custom widget that functions just like a Theme. Here's a boiled-down version:

@immutable
class MyThemeData {
  MyThemeData({
    this.myPadding,
    this.myColor,
    this.myString
  });

  final Padding myPadding;
  final Color myColor;
  final String myString;
}

class MyTheme extends StatelessWidget {
  MyTheme({
    Key key,
    @required this.data,
    @required this.child
  }) : super(key: key);

  final MyThemeData data;
  final Widget child;

  static MyThemeData of(BuildContext context) {
    return (context.ancestorWidgetOfExactType(MyTheme) as MyTheme)?.data;
  }

  @override
  Widget build(BuildContext context) => child;
}

Now, you can just wrap the MaterialApp in a MyTheme widget:

MyTheme(
  data: MyThemeData(
    myPadding: ...,
    myColor: ...,
    ...
  ),
  child: ... (here goes the MaterialApp)
)

Then anywhere in your app, you can write MyTheme.of(context).myPadding.
You can adapt the MyThemeData class to your needs, storing anything you want.



来源:https://stackoverflow.com/questions/54072372/share-dimensions-between-widgets

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!