Flutter: ввод текста
За ввод текста во Flutter отвечает виджет TextField и соответствующий класс TextEditingController для управления вводом текста
Для примера отрисуем страницу авторизации. Сначала «Рыба»:
import 'package:flutter/material.dart';
import 'package:invent/globals.dart' as globals;
class Login extends StatefulWidget {
_LoginState createState() => _LoginState(); // сюда передаем текущее состояние страницы
}
class _LoginState extends State<Login> {// _ впереди класса, означает чтоб скрыть доступ из другх файлов
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Авторизация')),
body: Center(
),
);
}
}
Добавим надписи Логин и Пароль:
body: Center(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(10, 10, 10, 0),
child: Column(
children: [
Text('Логин:'),
Text('Пароль:',),
],
),
),
),
Далее необходимо рассказать о классе TextEditingController.
Данный класс имеет два конструктора:
TextEditingController({String text})
TextEditingController.fromValue(TextEditingValue value)
Первый конструктор в качестве параметра принимает начальное значение, которое затем будет отображаться в ассоциированном текстовом поле. Второй конструктор также принимает начальное значение, но в виде объекта TextEditingValue
TextEditingController позволяет контроллировать введенный и выделенный текст в поле ввода, для чего у него определены три свойства:
- selection: выделенный текст в виде объекта TextSelection
- text: текущий введенный текст в виде объекта String
- value: текущее значение в виде объекта TextEditingValue
При изменении ввода в текстовом поле связанный объект TextEditingController уведомляет слушателей об изменении. Для добавления слушателей — функций обработного вызова в классе определен метод addListener(). Все добавленные слушатели могут считать введенный текст, а также выделенный текст и таким образом узнать о произошедших изменениях.
Когда объект TextEditingController больше не нужен, у него надо вызвать метод dispose(). Это позволит освободить все ресурсы, используемые объектом.
Таким образом модифицируем код, добавив поля ввода для логина и пароля:
class _LoginState extends State<Login> {// _ впереди класса, означает чтоб скрыть доступ из другх файлов
final _controller1 = TextEditingController();
final _controller2 = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Авторизация')),
body: Center(
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(10, 10, 10, 0),
child: Column(
children: [
Text('Логин:'),
TextField(
style: TextStyle(fontSize: 22),
controller: _controller1
),
Text('Пароль:',),
TextField(
style: TextStyle(fontSize: 22),
controller: _controller2
),
],
),
),
),
);
}
}
Теперь создадим обработчики событий ввода и начальное заполнение контроллеров.
class _LoginState extends State<Login> {// _ впереди класса, означает чтоб скрыть доступ из другх файлов
final _controller1 = TextEditingController();
final _controller2 = TextEditingController();
_changField(){
print("-чтото повводили..");
}
@override
void initState() {
super.initState();
_controller1.text = "Логин";
_controller1.addListener(_changField);
_controller2.text = "***";
_controller2.addListener(_changField);
}
@override
void dispose() {
_controller1.dispose();
_controller2.dispose();
super.dispose();
}
Результат:

Если поля ввода заполняются например из списка, то заполнение начальных значений и их сохранение можно организовать как-то так:
TextField(
style: TextStyle(fontSize: 22),
controller: TextEditingController()..text = globals.ComfortList[index]["temp"].toString(),
onChanged: (text) {
globals.ComfortList[index]["temp"]=text;
print("Введено: {$index},{$text}");
}
Получится:
