Reputation: 591
I started learning flutter recently. In my app window when I push a button a bottom sheet modal will appear like in the below image. When I typing in the 'Amount' text field, the previously typed 'Title' text filed content is disappeared. Why is this happen and how to solve this?
This my code related to read text field inputs.
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,
)
],
),
),
),
);
}
}
Upvotes: 1
Views: 128
Reputation: 46
You can't use setState
in Stateless Widget
Just refractor with right click on StatelessWidget
, select refractor then select Convert to StatefulWidget
Upvotes: 1
Reputation: 591
I solved this issue by just replacing StatelessWidget with 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,
)
],
),
),
),
);
}
}
Upvotes: 1