Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Sep 9, 2025. It is now read-only.

A code generator to write widgets as function without loosing the benefits of classes.

NotificationsYou must be signed in to change notification settings

rrousselGit/functional_widget

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Buildpub packagepub package

Widgets are cool. But classes are quite verbose:

classFooextendsStatelessWidget {finalint value;finalint value2;constFoo({Key key,this.value,this.value2}):super(key: key);@overrideWidgetbuild(BuildContext context) {returnText('$value $value2');  }}

So much code for something that could be done much better using a plain function:

Widgetfoo(BuildContext context, {int value,int value2 }) {returnText('$value $value2');}

The problem is, using functions instead of classes is not recommended:

... Or is it?


functional_widgets, is an attempt to solve this issue, using a code generator.

Simply write your widget as a function, decorate it with a@swidget, and thenthis library will generate a class for you to use.

As the added benefit, you also get for free the ability to inspect the parameterspassed to your widgets in the devtool

Example

You write:

@swidgetWidgetfoo(BuildContext context,int value) {returnText('$value');}

It generates:

classFooextendsStatelessWidget {constFoo(this.value, {Key key}):super(key: key);finalint value;@overrideWidgetbuild(BuildContext context) {returnfoo(context, value);  }@overridevoiddebugFillProperties(DiagnosticPropertiesBuilder properties) {super.debugFillProperties(properties);    properties.add(IntProperty('value', value));  }}

And then you use it:

runApp(Foo(42));

How to use

Install (builder)

There are a few separate packages you need to install:

  • functional_widget_annotation, a package containing decorators. You mustinstall it asdependencies.
  • functional_widget, a code-generator that uses the decorators from the previouspackages to generate your widget.
  • build_runner, a dependency that all applications using code-generation should have

Yourpubspec.yaml should look like:

dependencies:functional_widget_annotation:^0.8.0dev_dependencies:functional_widget:^0.8.0build_runner:^1.9.0

That's it!

You can then start the code-generator with:

flutter pub run build_runner watch

Customize the output

It is possible to customize the output of the generator by using different decorators or configuring default values inbuild.yaml file.

build.yaml change the default behavior of a configuration.

# build.yamltargets:$default:builders:functional_widget:options:# Default values:debugFillProperties:falsewidgetType:stateless# or 'hook'

FunctionalWidget decorator will override the default behavior for one specific widget.

@FunctionalWidget(  debugFillProperties:true,  widgetType:FunctionalWidgetType.hook,)Widgetfoo()=>Container();

debugFillProperties override

Widgets can be overridedebugFillProperties to display custom fields on the widget inspector.functional_widget offer to generate these bits for your, by enablingdebugFillProperties option.

For this to work, it is required to add the following import:

import'package:flutter/foundation.dart';

Example:

(You write)

import'package:flutter/foundation.dart';part'example.g.dart';@swidgetWidgetexample(int foo,String bar)=>Container();

(It generates)

classExampleextendsStatelessWidget {constExample(this.foo,this.bar, {Key key}):super(key: key);finalint foo;finalString bar;@overrideWidgetbuild(BuildContext _context)=>example(foo, bar);@overridevoiddebugFillProperties(DiagnosticPropertiesBuilder properties) {super.debugFillProperties(properties);    properties.add(IntProperty('foo', foo));    properties.add(StringProperty('bar', bar));  }}

Generate different type of widgets

By default, the generated widget by@FunctionalWidget() is aStatelessWidget.

It is possible to generate:

There are a few ways to do so:

  • With the shorthand@hwidget decorator:

    @hwidget// Creates a HookWidgetWidgetexample(int foo,String bar)=>Container();@hcwidget// Creates a HookConsumerWidgetWidgetexample(WidgetRef ref,int foo,String bar)=>Container();@cwidget// Creates a ConsumerWidgetWidgetexample(WidgetRef ref,int foo,String bar)=>Container();
  • Throughbuild.yaml:

    # build.yamltargets:$default:builders:functional_widget:options:widgetType:hook

    then used as:

    @FunctionalWidget()Widgetexample(int foo,String bar)=>Container();
  • With parameters on the@FunctionalWidget decorator:

    @FunctionalWidget(widgetType:FunctionalWidgetType.hook)Widgetexample(int foo,String bar)=>Container();

In any cases, you will need to install the corresponding package separately, byadding eitherflutter_hooks/flutter_riverpod orhooks_riverpod to yourpubspec.yaml

dependencies:flutter_hooks:# some version number

All the potential function prototypes

functional_widget will inject widget specific parameters if you ask for them.You can potentially write any of the following:

Widgetfoo();Widgetfoo(BuildContext context);Widgetfoo(Key key);Widgetfoo(BuildContext context,Key key);Widgetfoo(Key key,BuildContext context);

You can then add however many arguments you likeafter the previously defined arguments. They will then be added to the class constructor and as a widget field:

  • positional
@swidgetWidgetfoo(int value)=>Text(value.toString());// USAGEFoo(42);
  • named:
@swidgetWidgetfoo({int value})=>Text(value.toString());// USAGEFoo(value:42);
  • A bit of everything:
@swidgetWidgetfoo(BuildContext context,int value, {int value2 }) {returnText('$value $value2');}// USAGEFoo(42, value2:24);

Private vs public widgets

In order to allow for private function definitions but exported widgets, alldecorated widget functions with a single underscore will generate an exported widget.

@swidgetWidget_foo(BuildContext context,int value, {int value2 }) {returnText('$value $value2');}// USAGEFoo(42, value2:24);

In order to keep generated widget private, do use two underscores:

@swidgetWidget__foo(BuildContext context,int value, {int value2 }) {returnText('$value $value2');}// USAGE_Foo(42, value2:24);

Sponsors

About

A code generator to write widgets as function without loosing the benefits of classes.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors16

Languages


[8]ページ先頭

©2009-2025 Movatter.jp