4
votes

I'm new to flutter and dart, and is a bit off related to inheritance. After having created a few forms, things get redundant, as we use the outline border on all the text fields, like this:

TextFormField(
    decoration: InputDecoration(
        labelText: 'Email',
        hintText: 'Your corporate email address',
        border: OutlineInputBorder()
    ),
)

What I want to create is a OutlinedTextFormField that I could just simply use as:

OutlinedTextFormField(
    labelText: 'Email',
    hintText: 'Your corporate email address',
)

What I want is an element is to have have all the available constructors in TextFormField + labelText and hintText. In the constructor, or elsewhere, I would build the InputDecoration etc based on what is our internal standard.

1

1 Answers

5
votes

Welcome to Flutter :) It's definitely possible, here's an example:


class OutlinedTextFormField extends StatelessWidget {
    final String labelText;
    final String hintText;

    OutlinedTextFormField({this.labelText, this.hintText});

    build(BuildContext context) {
        return TextFormField(
            decoration: InputDecoration(
                labelText: this.labelText,
                hintText: this.hintText,
                border: OutlineInputBorder()
            ));
    }
}

To give some context for what is going on here:

OutlineTextFormField extends Stateless widget. StatelessWidget comes from the Flutter Widgets library (or material or cupertino libraries). The StatelessWidget class has an abstract build method that its implementers must override. The build method contains the UI for your widget.

OutlineTextFormField is a full class, so you can define instance variables and methods for it. So, to pass in a labelText and hintText, you simply define those variables on the class, and then, in the constructor, you pass in those variables. In your build method, you can reference those variables to achieve the effect you describe.

Also worth noting is the syntax for the constructor. Dart has a few different ways of specifying constructor parameters. The two most common you'll find are positional parameters and named parameters. Positional parameters are required parameters, and named parameters, by default, are optional.

In our example, we're using two named paramaters, labelText and hintText. Named parameters are placed inside curly brackets. Dart allows direct assignment to class variables from the constructor parameters, thus the {this.labelText, this.hintText} syntax. You're effectively saying, I have two parameters, one named labelText, one named hintText, and I want to go ahead and assign them right away to the class variables of the same name.

Positional parameters, by contrast, do not require you to spell out their name when calling the constructor. The most common flutter widget that takes a positional parameter is Text. You create a text object by passing in one required positional parameter, and a variety of optional named ones. For example: Text('Im a required positional parameter', style: new TextStyle());

In order to use this example widget, you would use the following code:

new OutlinedTextFormField(labelText: 'Foo', hintText: 'Bar');