You are currently viewing Flutter TextField – Single and MultiLine

Flutter TextField – Single and MultiLine

Flutter TextField Tutorial and Example

This is a flutter textfield tutorial. We want to see how to create textfields with both single and multiple lines. This is important as textfields are the most commonly used user input widget. Most information in computers exist in text format hence this makes textfields one of the most important UI component, not just in flutter but all user interface frameworks.

Video Tutorial

If you prefer a video tutorial then check here:

What You Learn in This Tutorial

  1. How to render and use a TextField widget.
  2. How set and get data to a Textfield.
  3. Single and Multi-line textfield examples.
  4. How to get textfield data and show in a snackbar.

Role of TextView

Here are the most commonly used roles for textviews:

  1. As a user input widget. For users to type text values.
  2. For display - TextFields can also be used to display information. We can do this by making them uneditable or just leaving it editable but not treating the editted data seriously.

Types of TextFields

TextFields can be divided into two categories:

  1. Single Line TextField - Allow user input only one line.
  2. Multi Line TextField - users can input multiple lines. The number of lines can be specified.

TextField Companions.

Here are the companions of textfields in other programming languages and frameworks:

  1. EditText in native android(Java,Kotlin,C#).
  2. TextBox - In C# and VB.NET windows forms.
  3. JTextField - In Java swing.

Let's start.

But first let's look at the demo

Demo

Here's the demo for the simple app we build.

Let's proceed.

(a). pubspec.yaml

This is our configuration and dependencies file. We don't use any third party library.

name: mr_textfield
description: A new Flutter project.
dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^0.1.2
dev_dependencies:
  flutter_test:
    sdk: flutter

(b). main.dart

This is our main dart file. This will contain several classes we use. The only import we make is the material.dart. This will give us our UI widgets like the TextField.

We will have four classes:

class MyApp extends StatelessWidget {..}
class MrSingleTextField extends StatelessWidget {..}
class MrMultiLineTextFieldAndButton extends StatefulWidget {..}
class _TextFieldAndButtonState extends State<MrMultiLineTextFieldAndButton> {..}

The first one MyApp will represent our full application. It is what we will pass to our runApp() method to be inflated. In it build and return MaterialApp widget with title,theme and home. In the home we will supplu the appbar as well as the body. The body will comprise our SingleLine textField as well as the MultiLine TextField.

The next class defines our Single Line TextField. This will build us a stateless widget that will allow users to input single line texts.

Then the MrMultiLineTextFieldAndButton is our third class. It will build us a stateful widget with textfield and button. By deriving from the StatefulWidegt class, this class will have mutable state.
The State is the logic and internal state for a StatefulWidget. So we have to create the state for this class first:

Then the next class represents our State. This is where we will build and return our Multiline TextField and Button widget.

Here's the full code.

import 'package:flutter/material.dart';
//Our MyApp. Extends StatelessWidget
class MyApp extends StatelessWidget {
  //BuildContext represents a handle to the location of a widget in the widget tree.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter TextFields',
      theme: ThemeData(
        primarySwatch: Colors.orange,
      ),
      home: Scaffold(
       //Whether the body (and other floating widgets) should size themselves
        // to avoid the window's bottom padding.
        resizeToAvoidBottomPadding: false,
        appBar: AppBar(
          title: const Text('Text Fields'),
        ),
        body: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: MrSingleTextField(),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: MrMultiLineTextFieldAndButton(),
            ),
          ],
        ),
      ),
    );
  }
}
/// Displays text in a snackbar
_showInSnackBar(BuildContext context, String text) {
  Scaffold.of(context).showSnackBar(SnackBar(content: Text(text),));
}
/// Single-line text field widget
class MrSingleTextField extends StatelessWidget {
  final TextEditingController _singleTextFieldcontroller = TextEditingController();
  //<code>BuildContext is an abstract class representing a handle to the location of a widget in the widget tree.
  @override
  Widget build(BuildContext context) {
    //Container is a class that creates a widget that combines common painting, positioning, and sizing widgets.
    return Container(
      //set padding on all sides
      padding: const EdgeInsets.all(15.0),
      //we create BoxDecoration with the specified border and border radius
      decoration: BoxDecoration(
        border: Border.all(color: Colors.grey),
        borderRadius: BorderRadius.all(Radius.circular(10.0)),
      ),
       child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
      // TextField creates a Material Design text field.
          TextField(
        autocorrect: false, // turns off auto-correct
        controller: _singleTextFieldcontroller,
        // InputDecoration creates a bundle of the border, labels, icons, and styles used to decorate a Material Design text field.
        decoration: InputDecoration(
          hintText: 'Please Input Your text',
        ),
        //onChanged is called when the text being edited changes. Returns a string
        // print() prints a string representation of the object to the console.
        onChanged: (str) => print('Single-line text change: $str'),
        // onSubmitted is called when the user indicates that they are done editing the text in the field.
        //In this case we show the returned string in a snackbar
        onSubmitted: (str) => _showInSnackBar(context, '$str'),
      ),
      SizedBox(height: 10.0),
          FlatButton(
            onPressed: () => _showInSnackBar(context,'${_singleTextFieldcontroller.text}',),
            child: const Text('Send'),
          ),
        ],
      ),
    );
  }
}
/// Multi-line text field widget with a submit button
/// StatefulWidegt is a widget that has mutable state.
class MrMultiLineTextFieldAndButton extends StatefulWidget {
  MrMultiLineTextFieldAndButton({Key key}) : super(key: key);
  @override
  createState() => _TextFieldAndButtonState();
}
// State is information that can be read synchronously when the widget is built and that might change during the lifetime of the widget.
// It is the logic and internal state for a StatefulWidget.
class _TextFieldAndButtonState extends State<MrMultiLineTextFieldAndButton> {
  //TextEditingController A controller for an editable text field.
  // Whenever the user modifies a text field with an associated TextEditingController,
  //the text field updates value and the controller notifies its listeners.
  final TextEditingController _multiLineTextFieldcontroller = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(15.0),
      decoration: BoxDecoration(
        border: Border.all(color: Colors.grey),
        borderRadius: BorderRadius.all(Radius.circular(10.0)),
      ),
      //color: Colors.grey,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          TextField(
            controller: _multiLineTextFieldcontroller,
            maxLines: 10,
            decoration: InputDecoration(
              hintText: 'Please Type Your Text then click submit',
            ),
            onChanged: (str) => print('Multi-line text change: $str'),
            onSubmitted: (str) => print('This will not get called when return is pressed'),
          ),
          SizedBox(height: 10.0),
          FlatButton(
            onPressed: () => _showInSnackBar(context,'${_multiLineTextFieldcontroller.text}',),
            child: const Text('Submit'),
          ),
        ],
      ),
    );
  }
}
//Our main method
void main() {
  runApp(MyApp());
}

Leave a Reply