Flutter Inputs & Forms

Collecting user input with text fields and forms

📝 What are Input Widgets?

Input widgets like TextField and Form collect user data through text entry. They support validation, formatting, and various input types like email, password, and numbers for interactive applications.


// Simple text input
TextField(
  decoration: InputDecoration(
    labelText: 'Enter your name',
  ),
)
                                    

Output:

Input Features

📝

TextField

Basic text input widget

TextField(
  decoration: InputDecoration(
    hintText: 'Type here',
  ),
)

Validation

Validate user input

TextFormField(
  validator: (value) {
    if (value?.isEmpty ?? true) {
      return 'Required';
    }
    return null;
  },
)
🔢

Input Types

Different keyboard types

TextField(
  keyboardType: 
    TextInputType.number,
)
🔒

Password

Hide sensitive input

TextField(
  obscureText: true,
)

🔹 Basic TextField

Simple text input with decoration:

TextField(
  decoration: InputDecoration(
    labelText: 'Username',
    hintText: 'Enter your username',
    border: OutlineInputBorder(),
    prefixIcon: Icon(Icons.person),
  ),
  onChanged: (value) {
    print('Input: $value');
  },
)

Output:

👤

🔹 TextField Controller

Control and access TextField value:

class MyForm extends StatefulWidget {
  @override
  _MyFormState createState() => _MyFormState();
}

class _MyFormState extends State {
  final TextEditingController _controller = TextEditingController();

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          controller: _controller,
          decoration: InputDecoration(labelText: 'Name'),
        ),
        ElevatedButton(
          onPressed: () {
            print('Value: ${_controller.text}');
          },
          child: Text('Submit'),
        ),
      ],
    );
  }
}

🔹 Password Field

Hide sensitive text input:

bool _obscureText = true;

TextField(
  obscureText: _obscureText,
  decoration: InputDecoration(
    labelText: 'Password',
    border: OutlineInputBorder(),
    prefixIcon: Icon(Icons.lock),
    suffixIcon: IconButton(
      icon: Icon(
        _obscureText ? Icons.visibility : Icons.visibility_off,
      ),
      onPressed: () {
        setState(() {
          _obscureText = !_obscureText;
        });
      },
    ),
  ),
)

Output:

🔒 👁️

🔹 Form with Validation

Create forms with validation logic:

class MyForm extends StatefulWidget {
  @override
  _MyFormState createState() => _MyFormState();
}

class _MyFormState extends State {
  final _formKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        children: [
          TextFormField(
            decoration: InputDecoration(labelText: 'Email'),
            validator: (value) {
              if (value == null || value.isEmpty) {
                return 'Please enter email';
              }
              if (!value.contains('@')) {
                return 'Please enter valid email';
              }
              return null;
            },
          ),
          ElevatedButton(
            onPressed: () {
              if (_formKey.currentState!.validate()) {
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Form is valid')),
                );
              }
            },
            child: Text('Submit'),
          ),
        ],
      ),
    );
  }
}

🔹 Different Input Types

Use appropriate keyboard types:

// Email keyboard
TextField(
  keyboardType: TextInputType.emailAddress,
  decoration: InputDecoration(labelText: 'Email'),
)

// Number keyboard
TextField(
  keyboardType: TextInputType.number,
  decoration: InputDecoration(labelText: 'Phone'),
)

// Multiline text
TextField(
  keyboardType: TextInputType.multiline,
  maxLines: 4,
  decoration: InputDecoration(labelText: 'Message'),
)

// URL keyboard
TextField(
  keyboardType: TextInputType.url,
  decoration: InputDecoration(labelText: 'Website'),
)

🔹 Complete Login Form

Full example with email and password:

class LoginForm extends StatefulWidget {
  @override
  _LoginFormState createState() => _LoginFormState();
}

class _LoginFormState extends State {
  final _formKey = GlobalKey();
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        children: [
          TextFormField(
            controller: _emailController,
            decoration: InputDecoration(
              labelText: 'Email',
              prefixIcon: Icon(Icons.email),
              border: OutlineInputBorder(),
            ),
            keyboardType: TextInputType.emailAddress,
            validator: (value) {
              if (value?.isEmpty ?? true) return 'Enter email';
              if (!value!.contains('@')) return 'Invalid email';
              return null;
            },
          ),
          SizedBox(height: 16),
          TextFormField(
            controller: _passwordController,
            decoration: InputDecoration(
              labelText: 'Password',
              prefixIcon: Icon(Icons.lock),
              border: OutlineInputBorder(),
            ),
            obscureText: true,
            validator: (value) {
              if (value?.isEmpty ?? true) return 'Enter password';
              if (value!.length < 6) return 'Min 6 characters';
              return null;
            },
          ),
          SizedBox(height: 24),
          ElevatedButton(
            onPressed: () {
              if (_formKey.currentState!.validate()) {
                // Process login
                print('Login successful');
              }
            },
            child: Text('Login'),
          ),
        ],
      ),
    );
  }
}

🧠 Test Your Knowledge

Which property hides password text?