#flutter #input #flutter-layout
#трепетание #ввод #flutter-layout
Вопрос:
Недавно я начал изучать flutter. В окне моего приложения, когда я нажимаю кнопку, появится модальный нижний лист, как на изображении ниже. Когда я набираю текстовое поле «Сумма», ранее введенный текстовый файл «Заголовок» исчезает. Почему это происходит и как это решить?
Это мой код, связанный с вводом текстового поля для чтения.
import 'dart:io';
import './adaptive_flat_button.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class NewTransaction extends StatelessWidget {
final Function newTransactionHandler;
final titleController = TextEditingController();
final amountController = TextEditingController();
DateTime selectedDate;
NewTransaction(this.newTransactionHandler);
void addTx() {
if (amountController.text.isEmpty) {
return;
}
String titileTxt = titleController.text;
double amount = double.parse(amountController.text);
if (titileTxt.isEmpty || amount <= 0 || selectedDate == null) {
return;
}
newTransactionHandler(titileTxt, amount, selectedDate);
Navigator.of(context).pop();
}
void presentDatePicker() {
showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2019),
lastDate: DateTime.now())
.then((pickedDate) {
if (pickedDate == null) {
return;
}
selectedDate = pickedDate;
});
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Card(
elevation: 5,
child: Container(
padding: EdgeInsets.only(
top: 10,
left: 10,
right: 10,
bottom: MediaQuery.of(context).viewInsets.bottom 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextField(
decoration: InputDecoration(labelText: 'Title'),
controller: titleController,
onSubmitted: (_) => addTx(),
// onChanged: (val) {
// titleInput = val;
// },
),
TextField(
decoration: InputDecoration(labelText: 'Amount'),
controller: amountController,
keyboardType: TextInputType.phone,
onSubmitted: (_) => addTx(),
// onChanged: (val) {
// amountInput = val;
// },
),
Container(
height: 70,
child: Row(
children: [
Text(selectedDate == null
? 'No date chosen!'
: 'PickedDate: ${DateFormat.yMd().format(selectedDate)}'),
AdaptiveFlatButton('Choose Date', presentDatePicker),
],
),
),
RaisedButton(
color: Theme.of(context).primaryColor,
textColor: Theme.of(context).textTheme.button.color,
child: Text(
'Add Transaction',
),
onPressed: addTx,
)
],
),
),
),
);
}
}
Комментарии:
1. зачем вам onSubmitted ? Я думаю, это потому, что это вызывает это, если
(amountController.text.isEmpty) { return; }
.2. Я удалил onSubmitted . Но у меня все еще есть эта проблема.
3. удалены оба??
4. Удалено при отправке в текстовых полях.
Ответ №1:
Я решил эту проблему, просто заменив StatelessWidget на StatefulWidget.
import 'dart:io';
import './adaptive_flat_button.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class NewTransaction extends StatefulWidget {
final Function newTransactionHandler;
NewTransaction(this.newTransactionHandler) {
print('Constructor NewTRansaction');
}
@override
_NewTransactionState createState() {
print('CreateState NewTransaction');
return _NewTransactionState();
}
}
class _NewTransactionState extends State<NewTransaction> {
final _titleController = TextEditingController();
final _amountController = TextEditingController();
DateTime selectedDate;
_NewTransactionState() {
print('Constructor NewTransaction State');
}
@override
void initState() {
// TODO: implement initState
print('initState()');
super.initState();
}
@override
void didUpdateWidget(covariant NewTransaction oldWidget) {
// TODO: implement didUpdateWidget
print('didUpdate()');
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
// TODO: implement dispose
print('dispose()');
super.dispose();
}
void _addTx() {
if (_amountController.text.isEmpty) {
return;
}
String titileTxt = _titleController.text;
double amount = double.parse(_amountController.text);
if (titileTxt.isEmpty || amount <= 0 || selectedDate == null) {
return;
}
widget.newTransactionHandler(titileTxt, amount, selectedDate);
Navigator.of(context).pop();
}
void _presentDatePicker() {
showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2019),
lastDate: DateTime.now())
.then((pickedDate) {
if (pickedDate == null) {
return;
}
setState(() {
selectedDate = pickedDate;
});
});
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Card(
elevation: 5,
child: Container(
padding: EdgeInsets.only(
top: 10,
left: 10,
right: 10,
bottom: MediaQuery.of(context).viewInsets.bottom 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextField(
decoration: InputDecoration(labelText: 'Title'),
controller: _titleController,
onSubmitted: (_) => _addTx(),
// onChanged: (val) {
// titleInput = val;
// },
),
TextField(
decoration: InputDecoration(labelText: 'Amount'),
controller: _amountController,
keyboardType: TextInputType.phone,
onSubmitted: (_) => _addTx(),
// onChanged: (val) {
// amountInput = val;
// },
),
Container(
height: 70,
child: Row(
children: [
Text(selectedDate == null
? 'No date chosen!'
: 'PickedDate: ${DateFormat.yMd().format(selectedDate)}'),
AdaptiveFlatButton('Choose Date', _presentDatePicker),
],
),
),
RaisedButton(
color: Theme.of(context).primaryColor,
textColor: Theme.of(context).textTheme.button.color,
child: Text(
'Add Transaction',
),
onPressed: _addTx,
)
],
),
),
),
);
}
}
Ответ №2:
Вы не можете использовать setState
в виджете без состояния
Просто щелкните правой кнопкой мыши StatelessWidget
, выберите refractor, затем выберите Преобразовать в StatefulWidget