Два поля TextFormField наподобие конвертера в две стороны
Не могу разобраться как осуществить взаимодействие между двумя TextFormField. Требуется (для примера): вводя число в первом поле, отображать утроенное значение первого поля во втором, и наоборот - вводя во второе поле число, отображать поделенное на три значение второго поля. Проблема в том, что поля либо рекурсивно друг друга изменяют, либо происходит что-то совсем непонятное. Просто отобразить текст из одного поля в другое и наоборот - все получается. Но при вычислениях все время какие-то ошибки. Может я неправильно работаю с числами? Закомментировано то, что приводит к ошибкам.
import 'package:flutter/material.dart';
class MyPage extends StatefulWidget
{
MyPage({Key? key}) : super(key: key);
@override
_pageState createState() => _pageState();
}
class _pageState extends State<MyPage>
{
final myController1 = TextEditingController();
final myController2 = TextEditingController();
@override
void initState() {
super.initState();
// Начинаем слушать изменения.
myController1.addListener(() => _listener('textField1'));
myController2.addListener(() => _listener('textField2'));
}
//Слушатель
void _listener(String textField) {
switch (textField) {
case ('textField1'):
myController2.value = TextEditingValue(
//---!!!---
//text: (int.parse(myController1.text) * 3).toString(),
text: myController1.text,
selection: TextSelection.fromPosition(
TextPosition(offset: myController1.text.length),
),
);
break;
case ('textField2'):
myController1.value = TextEditingValue(
//---!!!---
//text: (int.parse(myController2.text) / 3).toString(),
text: myController2.text,
selection: TextSelection.fromPosition(
TextPosition(offset: myController2.text.length),
),
);
break;
}
}
@override
void dispose() {
myController1.dispose();
myController2.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextFormField(
keyboardType: TextInputType.number,
controller: myController1,
),
TextFormField(
keyboardType: TextInputType.number,
controller: myController2,
),
],
),
),
);
}
}
Ответы (1 шт):
У вас проблема в том что, каждый раз каждый TextEditingController реагировал на изменения (своеобразная рекурсия происходила). Вот простое решение как можно сделать по другому:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: MyPage(),
);
}
}
class MyPage extends StatefulWidget {
const MyPage({Key? key}) : super(key: key);
@override
_PageState createState() => _PageState();
}
class _PageState extends State<MyPage> {
late final myController1 = TextEditingController();
late final myController2 = TextEditingController();
@override
void dispose() {
myController1.dispose();
myController2.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextFormField(
keyboardType: TextInputType.number,
controller: myController1,
onChanged: (String s) {
if (s.isEmpty) {
myController2.text = '';
} else {
myController2.text = (int.parse(s) * 3).toString();
}
},
),
TextFormField(
keyboardType: TextInputType.number,
controller: myController2,
onChanged: (String s) {
if (s.isEmpty) {
myController1.text = '';
} else {
myController1.text = (int.parse(s) / 3).toString();
}
},
),
],
),
),
);
}
}
