TextEditingController

Последнее обновление: 12.02.2021

Класс TextEditingController предназначен для управления ввода текста в виджет TextField.

TextEditingController устанавливается с помощью параметра controller конструктора классов TextField и TextFormField.

Данный класс имеет два конструктора:

TextEditingController({String text})
TextEditingController.fromValue(TextEditingValue value)

Первый конструктор в качестве параметра принимает начальное значение, которое затем будет отображаться в ассоциированном текстовом поле. Второй конструктор также принимает начальное значение, но в виде объекта TextEditingValue

TextEditingController позволяет контроллировать введенный и выделенный текст в поле ввода, для чего у него определены три свойства:

  • selection: выделенный текст в виде объекта TextSelection

  • text: текущий введенный текст в виде объекта String

  • value: текущее значение в виде объекта TextEditingValue

При изменении ввода в текстовом поле связанный объект TextEditingController уведомляет слушателей об изменении. Для добавления слушателей - функций обработного вызова в классе определен метод addListener(). Все добавленные слушатели могут считать введенный текст, а также выделенный текст и таким образом узнать о произошедших изменениях.

Когда объект TextEditingController больше не нужен, у него надо вызвать метод dispose(). Это позволит осовободить все ресурсы, используемые объектом.

Вначале определим простейшее приложение с использованием TextEditingController, который задает начальное значение для текстового поля:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
      home:  Scaffold(
        body: Person(),
        appBar: AppBar(title: Text("METANIT.COM")))
  ));
}

class Person extends StatefulWidget {

  Person({ Key key}) : super(key: key);

  @override
  _PersonState createState() => _PersonState();
}
class _PersonState extends State<Person>{

  String _name = "Tom";
  final _controller = TextEditingController();

  @override
  void initState() {
    super.initState();
    _controller.text = _name;
  }
  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {

    return Column(children:[
      Text("Имя пользователя: $_name", style: TextStyle(fontSize: 22)),
      TextField(
          style: TextStyle(fontSize: 22),
          controller: _controller)
    ],
    crossAxisAlignment: CrossAxisAlignment.start);
  }
}

Для виджета Person в данном случае определяется состояние в виде класса _PersonState. Класс _PersonState хранит состояние в виде переменной _name - условное имя пользователя. Но кроме того _PersonState также определяет константу _controller, которая представляет объект TextEditingController, с помощью которого мы будем отслеживать измнения переменной _name.

По умолчанию переменная _name уже имеет начальное значение - "Tom". И чтобы передать это значение в контроллер, переопределяем метод initState класса State. Этот метод призван инициализировать состояние объекта State. И в данном случае мы передаем свойству text объекта TextEditingController значение переменной _name. Благодаря этому текстовое поле получит начальное значение.

Для того, чтобы объект TextEditingController освободил все связанные с ним ресурсы, в классе состояния переопределяем метод dispose(), в котором вызываем метод dispose() контроллера.

Далее при создании виджета TextField в его конструкторе устанавливаем используемый контроллер:

controller: _controller

В итоге при запуске приложения текстовое поле получит начальное значение:

TextEditingController и TextField в Flutter

Теперь добавим обработку изменения текста:

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
      home:  Scaffold(
        body: Person(),
        appBar: AppBar(title: Text("METANIT.COM")))
  ));
}

class Person extends StatefulWidget {

  Person({ Key key}) : super(key: key);

  @override
  _PersonState createState() => _PersonState();
}
class _PersonState extends State<Person>{

  String _name = "Tom";
  final _controller = TextEditingController();

  _changeName(){
    setState(() =>_name = _controller.text);
  }

  @override
  void initState() {
    super.initState();
    _controller.text = _name;
    _controller.addListener(_changeName);
  }
  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {

    return Column(children:[
      Text("Имя пользователя: $_name", style: TextStyle(fontSize: 22)),
      TextField(
          style: TextStyle(fontSize: 22),
          controller: _controller)
    ],
    crossAxisAlignment: CrossAxisAlignment.start);
  }
}

При вводе весь вводимый текст будет храниться в свойстве text объекта TextEditingController. Для его получения и изменения переменной _name здесь определен метод _changeName:

_changeName(){
    setState(() =>_name = _controller.text);
}

Но когда вызывать данный метод? Для отслеживания изменений при инициализации состояния в методе initState() вызываем у TextEditingController метод addListener() и в него передаем ту функцию, которая будет выполняться при изменении текста в TextEditingController.

_controller.addListener(_changeName);

Метод addListener() принимает функцию, которая не принимает никаких параметров и ничего не возвращает - то есть в данном случае соответствует определению метода _changeName(). Однако мы могли и явным образом вызвать метод _changeName:

_controller.addListener((){
      _changeName();
});

В итоге при изменении текста в текстовом поле также будет изменяться и состояние виджета Person:

TextEditingController и addListener для TextField в Flutter
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850