Home > Software engineering >  How to extract TextFormField as reusable widget in flutter
How to extract TextFormField as reusable widget in flutter

Time:04-22

I want to make my flutter project highly manageable, apply clean code and maintain DRY concept strictly. There are a lot of input elements in any flutter project. So I want to make this element as a separate widget so that if I want to change in future then I will change in one place. Here is my approach:

import 'package:flutter/material.dart';

import '../utility/validatation.dart';

class RegistrationPage extends StatefulWidget {
  static const String routeName = '/registrationPage';

  @override
  State<RegistrationPage> createState() => _RegistrationPageState();
}

class _RegistrationPageState extends State<RegistrationPage> {
  final _formKey = GlobalKey<FormState>();
  final TextEditingController nameInput = TextEditingController();
  final TextEditingController businessName = TextEditingController();
  final TextEditingController productTypeId = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: new Form(
        key: _formKey,
        autovalidateMode: AutovalidateMode.onUserInteraction,
        child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
          Container(
            height: 70,
            margin: EdgeInsets.only(bottom: 50),
            child: Image(image: AssetImage('assets/logo.png')),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 30.0),
            child: TextInput(inputController: nameInput, label: 'আপনার নাম'),
          ),
          ElevatedButton(
            onPressed: () {
              if (_formKey.currentState!.validate()) {
                _register(context);
              }
            },
            child: Text('Next'),
          )
        ]),
      ),
    );
  }

  void _register(BuildContext context) {}
}

class TextInput extends StatelessWidget {
  const TextInput({
    Key? key,
    required this.inputController,
    required this.label,
  }) : super(key: key);

  final TextEditingController inputController;
  final String label;

  @override
  Widget build(BuildContext context) {
    return TextFormField(
      controller: inputController,
      keyboardType: TextInputType.text,
      decoration: const InputDecoration(
        border: UnderlineInputBorder(),
        prefixIcon: Icon(Icons.phone),
        labelText: label,
      ),
      validator: (value) {
        return Validation.required(value);
      },
    );
  }
}

But I got this error:

enter image description here

What is wrong in my code? Is there any problem in my approach or should I stop thinking to refactor my code as I do? Please also suggest if there is any smarter way to make code more clean and manageable.

CodePudding user response:

Oh I see so you have this

            class TextInput extends StatelessWidget {
          const TextInput({
            Key? key,
            required this.inputController,
            required this.label,
          }) : super(key: key);
        
          final TextEditingController inputController;
          final String label;
        
          @override
          Widget build(BuildContext context) {
    
            return TextFormField(
              controller: inputController,
              keyboardType: TextInputType.text,
    // Notice the const here right?
    // So the idea is that decoration objects could rebuild to either change one thing or the other, so 'label' here cannot be a constant
//So to solve this InputDecoration should not have const.
              decoration: const InputDecoration(
                border: UnderlineInputBorder(),
                prefixIcon: Icon(Icons.phone),
                labelText: label,
              ),
              validator: (value) {
                return Validation.required(value);
              },
            );
          }
        }

CodePudding user response:

Since you are using a variable in InputDecoration, you should not declare InputDecoration with const keyword.

  • Related