S-Man
S-Man

Reputation: 23676

How to correctly extract/composite custom widgets and handle their child fields

In my widget tree, I have several TextField widgets. All have the same decoration but different onChanged actions:

Widget _buildTextField() {
  return TextField (
    decoration: InputDecoraction(
      border: OutlineInputBorder()
    ),
    onChanged: (text) {
      doSth();
    }
  );
}

Now I want to reduce the code duplication and was trying to extract the TextField with the duplicated decoration field into a CustomTextField. I read that with Flutter composition is over inheritance, so I tried to compose it this way:

class CustomTextField extends StatefulWidget {
  @override
  _CustomTextFieldState createState() => _CustomTextFieldState();
}

class _CustomTextFieldState extends State<CustomTextField> {    
  @override
  Widget build(BuildContext context) {
    return Container(
      child: TextField(
        decoration: InputDecoration(     //   <-- the decoration field
          border: OutlineInputBorder(),
        ),
      ),
    );
  }
}

At the other side I did:

Widget _buildTextField() {
  return CustomTextField (               //   <-- new CustomTextField without decoration
    onChanged: (text) {                  //   <-- Problem: "Parameter is not defined"
      doSth();
    }
  );
}

But now the onChanged call is not accepted. So, what is the correct way to extract own widgets and handle the child fields?

Upvotes: 0

Views: 286

Answers (1)

lazos
lazos

Reputation: 1075

You need to register a callback function

class CustomTextField extends StatefulWidget {
  final Function onChange;

  const CustomTextField({Key key, this.onChange}) : super(key: key);

  @override
  _CustomTextFieldState createState() => _CustomTextFieldState();
}

class _CustomTextFieldState extends State<CustomTextField> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: TextField(
        decoration: InputDecoration(
          //   <-- the decoration field
          border: OutlineInputBorder(),
        ),
        onChanged: widget.onChange,
      ),
    );
  }
}

and then

  child: CustomTextField(
    onChange: (item) {
      print(item);
    },
  ),

Upvotes: 1

Related Questions