Skip to main content

Handling Text Input

1. Using TextField Widget

Property Values Description
controller TextEditingController Controls the text field's value and selection.
decoration InputDecoration Customizes the appearance of the text field (e.g., label, hint).
keyboardType TextInputType Determines the type of keyboard to show (e.g., TextInputType.text, TextInputType.number).
obscureText bool Displays input as bullets (e.g., for passwords).
maxLines int? Number of lines the text field can display (null for unlimited).
onSubmitted Function(String)? Callback when the user submits the text (e.g., pressing Enter).

Example: Basic TextField

TextField(
  decoration: InputDecoration(
    labelText: 'Enter your name',
    hintText: 'Type here...',
  ),
)

Example: Password Field

TextField(
  obscureText: true,
  decoration: InputDecoration(
    labelText: 'Password',
    suffixIcon: IconButton(
      icon: Icon(Icons.visibility),
      onPressed: () {},
    ),
  ),
)
Note: Use TextFormField for form validation and integration with Form.

2. Using TextFormField Widget

Property Values Description
controller TextEditingController Controls the text input field's value and selection.
decoration InputDecoration Defines the visual appearance and hint text of the field.
keyboardType TextInputType Specifies the type of keyboard to show (e.g., TextInputType.text, TextInputType.number).
obscureText bool Whether to hide the input (e.g., for passwords).
maxLines int Maximum number of lines the field can expand to. Default is 1.
onChanged Function(String) Callback when the text changes.
validator Function(String) Validation function returning an error message or null.

Example: Basic TextFormField Usage

TextFormField(
  controller: TextEditingController(),
  decoration: InputDecoration(
    labelText: 'Enter your name',
    hintText: 'Name',
  ),
  validator: (value) {
    if (value == null || value.isEmpty) {
      return 'Please enter some text';
    }
    return null;
  },
)

Example: Password TextFormField

TextFormField(
  controller: TextEditingController(),
  decoration: InputDecoration(
    labelText: 'Password',
    hintText: 'Enter password',
    suffixIcon: IconButton(
      icon: Icon(Icons.visibility),
      onPressed: () {},
    ),
  ),
  obscureText: true,
  validator: (value) {
    if (value == null || value.length < 6) {
      return 'Password must be at least 6 characters';
    }
    return null;
  },
)
Note: The TextFormField widget is part of the Form widget and supports validation. It automatically integrates with TextEditingController for managing input state.

3. Using TextEditingController

The TextEditingController is a core class in Flutter for managing text input and state. It allows you to programmatically control the content of TextField or TextFormField widgets.

Property Description Example
text Current text value of the controller "Hello World"
selection Current text selection range TextSelection.collapsed(offset: 5)
value Complete TextEditingValue object TextEditingValue(text: "Hello", selection: ...)

Example: Initializing and Using TextEditingController

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("TextEditingController Example")),
        body: Padding(
          padding: EdgeInsets.all(16.0),
          child: MyTextField(),
        ),
      ),
    );
  }
}

class MyTextField extends StatefulWidget {
  @override
  _MyTextFieldState createState() => _MyTextFieldState();
}

class _MyTextFieldState extends State<MyTextField> {
  final TextEditingController _controller = TextEditingController();

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

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          controller: _controller,
          decoration: InputDecoration(hintText: "Enter text here"),
        ),
        SizedBox(height: 20),
        Text("Current text: ${_controller.text}"),
      ],
    );
  }
}

Example: Setting and Updating Text Programmatically

class TextUpdateExample extends StatefulWidget {
  @override
  _TextUpdateExampleState createState() => _TextUpdateExampleState();
}

class _TextUpdateExampleState extends State<TextUpdateExample> {
  final TextEditingController _controller = TextEditingController();

  void _updateText() {
    setState(() {
      _controller.text = "Updated text!";
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(controller: _controller),
        ElevatedButton(
          onPressed: _updateText,
          child: Text("Update Text"),
        ),
      ],
    );
  }
}
Note: Always dispose of TextEditingController in the dispose method to prevent memory leaks.
Warning: Do not call dispose on the controller more than once.

4. Managing Focus

Property Description Usage
focusNode Controls the focus state of a TextField or TextFormField. FocusNode focusNode = FocusNode();
requestFocus Requests focus for the widget associated with this FocusNode. FocusScope.of(context).requestFocus(focusNode);
unfocus Removes focus from the current widget. FocusScope.of(context).unfocus();

Example: Managing Focus in a TextField

class FocusExample extends StatefulWidget {
  @override
  _FocusExampleState createState() => _FocusExampleState();
}

class _FocusExampleState extends State<FocusExample> {
  final FocusNode _focusNode = FocusNode();

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

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          focusNode: _focusNode,
          decoration: InputDecoration(
            labelText: 'Enter text',
          ),
        ),
        ElevatedButton(
          onPressed: () {
            FocusScope.of(context).requestFocus(_focusNode);
          },
          child: Text('Focus TextField'),
        ),
      ],
    );
  }
}
Note: Always dispose of FocusNode instances to prevent memory leaks.

5. Using InputDecoration

Property Values Description
hintText String Displays a hint text when the field is empty
labelText String Displays a label above the input field
prefixText String Displays text before the input field
suffixText String Displays text after the input field
icon Widget Displays an icon at the start of the input field
border InputBorder Defines the border style of the input field
focusedBorder InputBorder Defines the border when the input is focused
enabledBorder InputBorder Defines the border when the input is enabled but not focused
errorText String Displays an error message below the input field
errorStyle TextStyle Defines the style of the error text

Example: Basic InputDecoration

TextField(
  decoration: InputDecoration(
    labelText: 'Email',
    hintText: 'Enter your email',
    prefixText: '@',
    icon: Icon(Icons.email),
  ),
)

Example: InputDecoration with Border

TextField(
  decoration: InputDecoration(
    labelText: 'Password',
    hintText: 'Enter your password',
    border: OutlineInputBorder(
      borderRadius: BorderRadius.circular(8),
      borderSide: BorderSide(color: Colors.blue),
    ),
    focusedBorder: OutlineInputBorder(
      borderRadius: BorderRadius.circular(8),
      borderSide: BorderSide(color: Colors.red, width: 2),
    ),
  ),
)

6. Customizing Input Borders

Property Values Description
border InputBorder.none, InputBorder.line, InputBorder.underline Defines the type of border to display around the input field.
focusedBorder OutlineInputBorder, UnderlineInputBorder Border displayed when the input field is focused.
enabledBorder OutlineInputBorder, UnderlineInputBorder Border displayed when the input field is enabled but not focused.
errorBorder OutlineInputBorder, UnderlineInputBorder Border displayed when the input field has an error.

Example: Customizing Input Borders

TextField(
  decoration: InputDecoration(
    border: OutlineInputBorder(
      borderSide: BorderSide(color: Colors.blue, width: 2.0),
    ),
    focusedBorder: OutlineInputBorder(
      borderSide: BorderSide(color: Colors.red, width: 2.0),
    ),
    enabledBorder: OutlineInputBorder(
      borderSide: BorderSide(color: Colors.grey, width: 1.0),
    ),
    errorBorder: OutlineInputBorder(
      borderSide: BorderSide(color: Colors.red, width: 2.0),
    ),
  ),
)

7. Using Input Formatters

Property Description Usage
inputFormatters Applies formatters to the input text [WhitelistingTextInputFormatter.digitsOnly]

Example: Restricting input to digits only

TextField(
  inputFormatters: [WhitelistingTextInputFormatter.digitsOnly],
  keyboardType: TextInputType.number,
)

Example: Formatting phone numbers

TextField(
  inputFormatters: [
    MaskedTextInputFormatter(
      mask: '(000) 000-0000',
      placeholder: ' ',
    ),
  ],
  keyboardType: TextInputType.phone,
)

8. Using Input Actions

Action Description Usage
TextInputAction.newline Indicates that the user wants to insert a new line. TextInputAction.newline
TextInputAction.done Indicates that the user is done editing and wants to close the keyboard. TextInputAction.done
TextInputAction.go Indicates that the user wants to go to a specific location or page. TextInputAction.go
TextInputAction.search Indicates that the user wants to search for content. TextInputAction.search
TextInputAction.send Indicates that the user wants to send a message or content. TextInputAction.send
TextInputAction.next Indicates that the user wants to move to the next input field. TextInputAction.next
TextInputAction.previous Indicates that the user wants to move to the previous input field. TextInputAction.previous

Example: Setting Input Action

TextField(
  keyboardType: TextInputType.text,
  textInputAction: TextInputAction.done,
  onSubmitted: (value) {
    print('Submitted value: $value');
  },
)

9. Using Keyboard Types

Keyboard Type Description Use Case
TextInputType.text Standard text input field. General text entry, such as names or comments.
TextInputType.number Input for numeric values only. Entering numbers like age, quantity, or price.
TextInputType.phone Input for phone numbers with dial pad. Collecting phone numbers with formatting assistance.
TextInputType.email Input for email addresses with @ symbol. Entering email addresses with auto-suggestions.
TextInputType.url Input for URLs with http/https prefix. Collecting web addresses or links.
TextInputType.datetime Input for date and time values. Entering dates or times with calendar pickers.
TextInputType.multiline Multi-line text input. Allowing users to enter paragraphs or descriptions.

Example: Setting Keyboard Type

TextField(
  keyboardType: TextInputType.number,
  decoration: InputDecoration(
    labelText: 'Age',
    hintText: 'Enter your age',
  ),
)

10. Implementing Obscure Text

Property Values Description
obscureText true | false When set to true, masks the text input (e.g., for passwords).
obscuringCharacter String Character used to obscure text. Defaults to •.

Example: Password Input Field

TextField(
  obscureText: true,
  decoration: InputDecoration(
    labelText: 'Password',
    hintText: 'Enter your password',
  ),
)
Note: Setting obscureText to true hides the actual text input and displays obscuringCharacter instead.

11. Using autocorrect and enableSuggestions Properties

Property Description Values Default
autocorrect Enables or disables automatic correction of words as the user types. true / false true
enableSuggestions Enables or disables suggestions for words as the user types. true / false true

Example: Configuring autocorrect and enableSuggestions

TextField(
  autocorrect: false,
  enableSuggestions: false,
)
Note: These properties are useful for custom input fields where you want to control the text input behavior, such as in password fields or when implementing custom keyboards.

Was this article helpful?