Dynamically created checkbox in flutter not changing the state on clicked - flutter

I am creating a checkbox field every time i press a button. but the generated checkbox is not changing the state when pressed, instead the next checkbox which is generated comes with the changed state.
I have attached the video of how it is working currently (https://imgur.com/a/75vE5cj )
my entire code goes like this :
class ToDoNotes extends StatelessWidget {
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
return new MaterialApp(
title: 'notes',
theme: new ThemeData(
primarySwatch: Colors.green,
),
home: new T_notes(),
); }}
class T_notes extends StatefulWidget {
static String tag = 'T_notes';
#override
_T_notesState createState() => new _T_notesState();
}
this is my code for creating checkbox dynamically.
class _T_notesState extends State<T_notes> {
bool rememberMe = false;
void _onRememberMeChanged(bool newValue) => setState(() {
rememberMe = newValue;
});
List<Widget> _children = [];
int _count = 0;
String input;
int i=0;
void _add() {
_children = List.from(_children)
..add(
CheckboxListTile(
value: rememberMe,
onChanged: _onRememberMeChanged,
title: new Text(input,style: TextStyle(color: Colors.black)),
controlAffinity: ListTileControlAffinity.leading,
activeColor: Colors.black,
)
);
setState(() {
++_count;
});
i++;
}
inside the widget build() inside the body i have the dynamic widget as:
#override
Widget build(BuildContext context) {
return new Scaffold(
resizeToAvoidBottomPadding: false,
body: ListView(
padding: EdgeInsets.all(28.0),
children: <Widget>[
SizedBox(height: 30),
new Row(
children: <Widget>[
SizedBox(width:0.2),
new Container(
width:200,
child: new TextField(
textAlign: TextAlign.left,
decoration: InputDecoration(
border: OutlineInputBorder(borderRadius: BorderRadius.circular(138.0)),
hintText: 'Enter the text',
),
onChanged: (val) {
input = val;
}
),
),
SizedBox(width:10),
new Container(
width: 80,
child:new Material(
borderRadius: BorderRadius.circular(30.5),
shadowColor: Colors.lightBlueAccent.shade100,
elevation: 1.0,
child: new MaterialButton(
onPressed: () {
_add();
},
child: Text('ADD', style: TextStyle(color: Colors.lightGreen,fontSize: 15)),
),
),
),
],
),
new Container(
height: 390,
child: ListView(children: _children),
),
],
) ,
);
}
I want the checkbox field to change the state properly on clicked.

Ok the thing here is that you need to have a model for each CheckboxListTile to preserve the state of each of the CheckboxListTiles.
This would be the model:
class ListTileModel {
bool enabled;
String text;
ListTileModel(this.enabled,this.text);
}
Then, when a user taps a Tile, just update the state of that particular row. What you have now is a general state for all your Tiles. So instead of having an array of widgets, have an array of models representing each row. And finally, use the a map function to build all your items
class _T_notesState extends State<T_notes> {
bool rememberMe = false;
List<ListTileModel> _items = [];
String input;
int i = 0;
void _add() {
_items.add(ListTileModel(false,input));
setState(() {});
}
#override
Widget build(BuildContext context) {
return new Scaffold(
resizeToAvoidBottomPadding: false,
body: ListView(
padding: EdgeInsets.all(28.0),
children: <Widget>[
SizedBox(height: 30),
new Row(
children: <Widget>[
SizedBox(width: 0.2),
new Container(
width: 200,
child: new TextField(
textAlign: TextAlign.left,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(138.0)),
hintText: 'Enter the text',
),
onChanged: (val) {
input = val;
}),
),
SizedBox(width: 10),
new Container(
width: 80,
child: new Material(
borderRadius: BorderRadius.circular(30.5),
shadowColor: Colors.lightBlueAccent.shade100,
elevation: 1.0,
child: new MaterialButton(
onPressed: () {
_add();
},
child: Text('ADD',
style:
TextStyle(color: Colors.lightGreen, fontSize: 15)),
),
),
),
],
),
new Container(
height: 390,
child: ListView(
children: _items
.map((item) => CheckboxListTile(
value: item.enabled,
onChanged: (enabled) {
item.enabled = enabled;
setState(() {});
},
title: new Text(item.text,
style: TextStyle(color: Colors.black)),
controlAffinity: ListTileControlAffinity.leading,
activeColor: Colors.black,
))
.toList()),
),
],
),
);
}
}

Related

Flutter Search Bar with ListView with Checkboxes

I want to create a widget like this.
This contains the Textfield, Once type something in the field, It will be sorting the list and show the results below the field. The result list shown below can also have a checkbox field to select multiple items from the result.
Is there any built-in flutter widget that can be useful for this case?
Or any other package to achieve this.
Following is the screenshot for reference.
I tried with RawAutoComplete widget.
Here is the code.
class SearchBarDemo extends StatelessWidget {
const SearchBarDemo({super.key});
static List<String> suggestons = [
"USA",
"UK",
"Uganda",
"Uruguay",
"United Arab Emirates"
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: RawAutocomplete(
optionsBuilder: (textEditingValue) {
if (textEditingValue.text == '') {
return const Iterable<String>.empty();
} else {
List<String> matches = <String>[];
matches.addAll(suggestons);
matches.retainWhere((s) {
return s
.toLowerCase()
.contains(textEditingValue.text.toLowerCase());
});
return matches;
}
},
fieldViewBuilder:
(context, textEditingController, focusNode, onFieldSubmitted) {
return TextField(
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(7),
),
hintText: 'Search',
contentPadding: EdgeInsets.symmetric(
vertical: 8,
horizontal: 4), // EdgeInsets.only(top: 8, left: 5),
prefixIcon: Container(
margin: EdgeInsets.symmetric(vertical: 8, horizontal: 4),
decoration: BoxDecoration(
shape: BoxShape.rectangle,
border: Border(
right: BorderSide(
color: Colors.grey.shade400,
),
),
),
child: Icon(
Icons.search,
color: Colors.grey.shade400,
),
),
),
controller: textEditingController,
focusNode: focusNode,
onSubmitted: (String value) {},
);
},
onSelected: (selection) {},
optionsViewBuilder: (context, onSelected, options) {
return Material(
child: SingleChildScrollView(
child: Column(
children: options.map((opt) {
return InkWell(
onTap: () {
onSelected(opt);
},
child: Column(
children: [
Container(
height: 50,
width: 250,
alignment: Alignment.topLeft,
child: Card(
child: SizedBox(
child: ListTile(
title: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
opt,
style: TextStyle(fontSize: 12),
),
Transform.scale(
scale: 0.8,
child: Checkbox(
value: false,
onChanged: (val) {},
),
),
],
),
),
),
),
),
],
),
);
}).toList(),
),
),
);
},
),
);
}
}
Output of the above code is:
It covers the whole screen and show the result content in center.
You can customize the filter logic. Also you may like SearchDelegate-class
class SearchBarDemo extends StatefulWidget {
const SearchBarDemo({super.key});
#override
State<SearchBarDemo> createState() => _SearchBarDemoState();
}
class _SearchBarDemoState extends State<SearchBarDemo> {
static List<String> suggestons = [
"USA",
"UK",
"Uganda",
"Uruguay",
"United Arab Emirates"
];
List<String> filterItems = [];
List<String> checkedItems = [];
late final TextEditingController controller = TextEditingController()
..addListener(() {
/// filter logic will be here
final text = controller.text.trim();
filterItems = suggestons
.where(
(element) => element.toLowerCase().startsWith(text.toLowerCase()))
.toList();
setState(() {});
});
#override
void dispose() {
controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
CupertinoTextField(
controller: controller,
),
Expanded(
child: ListView.builder(
itemCount: filterItems.length,
itemBuilder: (context, index) {
final bool isChecked =
checkedItems.contains(filterItems[index]);
return CheckboxListTile(
value: isChecked,
title: Text("${filterItems[index]}"),
onChanged: (value) {
if (isChecked) {
checkedItems.remove(filterItems[index]);
} else {
checkedItems.add(filterItems[index]);
}
setState(() {});
},
);
}),
),
],
));
}
}

when i typing in flutter textfield it type in backward direction how to solve it?

I have one page of technical skill and I want to add new textfield on onatap and get the value of it and remove that skill on ontap of delete button and this is working now but only problem was that the when i am typing in textfield its typing in backward direction(right to left i want to type left to right.)
import 'package:flutter/material.dart';
class Technical extends StatefulWidget {
const Technical({Key? key}) : super(key: key);
#override
State<Technical> createState() => _TechnicalState();
}
class _TechnicalState extends State<Technical> {
List<String> skill = <String>[];
List<TextEditingController> mycontroller = <TextEditingController>[];
#override
Widget build(BuildContext context) {
double h = MediaQuery.of(context).size.height;
double w = MediaQuery.of(context).size.width;
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
centerTitle: true,
elevation: 0,
backgroundColor: Colors.blue,
title: const Text(
'Technical Skills',
),
),
body: Column(
children: [
const Align(
alignment: Alignment.centerLeft,
child: Text(
'Enter Your Skills',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.blue,
),
),
),
...skill
.map(
(e) => Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 100,
child: TextField(
enableInteractiveSelection: true,
controller: TextEditingController(text: e),
onChanged: (String value) {
setState(() {
skill[skill.indexOf(e)] = value;
});
},
),
),
IconButton(
onPressed: () {
setState(() {
skill.remove(e);
mycontroller.clear();
print(e);
});
},
icon: const Icon(Icons.delete))
],
),
)
.toList(),
Center(
child: Text(
'$skill',
style: const TextStyle(fontSize: 30),
),
),
const Spacer(),
OutlinedButton(
onPressed: () {
setState(() {
skill.add("");
});
},
child: const Icon(Icons.add),
),
],
),
);
}
}
The issue is you are creating new controller on every state change, the cursor position is not handling in this.
So the solution will we
controller: TextEditingController.fromValue(
TextEditingValue(
text: e,
selection: TextSelection(
baseOffset: e.length,
extentOffset: e.length,
)),
),
With controller
class _TechnicalState extends State<Technical> {
List<String> skill = <String>[];
List<TextEditingController> mycontroller = <TextEditingController>[];
#override
Widget build(BuildContext context) {
double h = MediaQuery.of(context).size.height;
double w = MediaQuery.of(context).size.width;
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
centerTitle: true,
elevation: 0,
backgroundColor: Colors.blue,
title: const Text(
'Technical Skills',
),
),
body: Column(
children: [
const Align(
alignment: Alignment.centerLeft,
child: Text(
'Enter Your Skills',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.blue,
),
),
),
for (int i = 0; i < mycontroller.length; i++) row_build(i),
Center(
child: Text(
'$skill',
style: const TextStyle(fontSize: 30),
),
),
const Spacer(),
OutlinedButton(
onPressed: () {
mycontroller.add(TextEditingController());
setState(() {
skill.add("");
});
},
child: const Icon(Icons.add),
),
],
),
);
}
Row row_build(int i) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 100,
child: TextField(
enableInteractiveSelection: true,
controller: mycontroller[i],
onChanged: (String value) {
setState(() {
skill[i] = value;
});
},
),
),
IconButton(
onPressed: () {
setState(() {
skill.remove(skill[i]);
mycontroller.removeAt(i);
});
},
icon: const Icon(Icons.delete))
],
);
}
}
The textfield works fine for me (left to right)
Check your code if the textDirection property is set correctly to TextDirection.ltr instead of TextDirection.rtl
child: TextField(
textDirection: TextDirection.ltr,

The argument type 'List<dynamic>' can't be assigned to the parameter type 'String' in Flutter

In my project their are two Screens.
First Screen contains a floating Action Button, onclick navigates to second screen having form and on submitting the form. A Map is created with Key and value as the fields in the form. And map is added to the list.
Now using the Navigator. pop function the list is passed to the first screen and On printing the list on the console, error message comes saying,
Error: The argument type 'List' can't be assigned to the parameter type 'String' in Flutter
Code:
First Screen:
class donateNow extends StatefulWidget{
#override
_donateNowState createState() => _donateNowState();
}
class _donateNowState extends State<donateNow>{
List medicineCart = [];
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text('Donate Medicine'),
),
body: Container(),
floatingActionButton: FloatingActionButton.extended(
icon:Icon(Icons.add),
label: Text('Add Medicine'),
backgroundColor: kPrimaryColor,
foregroundColor: Colors.white,
elevation: 10.0,
splashColor: kPrimaryLightColor,
onPressed: (){
_navigateAndDisplayMedicine(context);
}
),
);
}
_navigateAndDisplayMedicine(BuildContext context) async{
List<dynamic> newList = await Navigator.push(context,
MaterialPageRoute(builder: (context) => medicineDetails()),
);
print('Medicine:'+ newList.toString());
}
}
Second Screen:
class medicineDetails extends StatefulWidget {
#override
State<StatefulWidget> createState() => medicineDetailsState();
}
class medicineDetailsState extends State<medicineDetails> {
final _formKey = GlobalKey<FormState>();
List medicineCart = [];
TextEditingController medName = new TextEditingController();
TextEditingController qty = new TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Add Medicine"),
),
body: Padding(
padding: EdgeInsets.only(top: 15.0, left: 10.0, right: 10.0),
child: Form(
key: _formKey,
child: ListView(
children: [
TextFormField(
obscureText: false,
style: Theme.of(context).textTheme.title,
onChanged: (value) {
debugPrint('Something change');
},
controller: medName,
validator: (value){
if(value.isEmpty)
return kMedicineNameNullError;
},
decoration: InputDecoration(
labelText: 'Medicine Name with Strength',
labelStyle: Theme.of(context).textTheme.title,
hintText: 'Enter Medicine Name',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0))),
),
Padding(
padding: EdgeInsets.only(top: 15.0, left: 10.0, bottom: 15.0),
child: TextFormField(
keyboardType: TextInputType.phone,
controller: qty,
validator: (value){
int val = int.parse(value);
if(value.isEmpty)
return kQuantityNullError;
else if(val<4){
return kMinimumQuantityError;
}
},
style: Theme.of(context).textTheme.title,
decoration: InputDecoration(
labelText: 'Quantity',
labelStyle: Theme.of(context).textTheme.title,
hintText: 'Enter the quantity',
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(5.0))),
),
),
Padding(
padding: EdgeInsets.only(top: 15.0, bottom: 15.0),
child: Row(
children: <Widget>[
// SaveButton(),
Expanded(
child: RaisedButton(
color: Color(0xFF574FC4),
textColor: Theme.of(context).primaryColorLight,
child: Text(
'Save',
textScaleFactor: 2.0,
),
onPressed: () {
if(_formKey.currentState.validate()){
_formKey.currentState.save();
KeyboardUtil.hideKeyboard(context);
var map = {
'Medicine Name': medName.text,
'Date': expDate.text,
'Quantity Type': qtyType,
'Quantity': qty.text,
};
medicineCart.add(map);
Navigator.pop(context,medicineCart);
debugPrint('Save Clicked');
}
})),
Expanded(
child: RaisedButton(
color: Color(0xFF574FC4),
textColor: Theme.of(context).primaryColorLight,
child: Text(
'Delete',
textScaleFactor: 2.0,
),
onPressed: () {
setState(() {
debugPrint('Delete Clicked');
//print(medicineCart);
});
}))
],
),
)
],
),
),
),
);
}
}
The issue here is that you're trying to assign a List<dynamic> to a String variable - which seems to be done when you're trying to pass medicineCart on Navigator.pop(). A quick workaround here is to encode your List to String then decode it back again using jsonEncode() and jsonDecode().

raised button does not shows answer until I select a drop down item even after assigning a default value

I was making a simple S.I Calculator which has a field for principal amount intrest, and time along with that i have a dropdown to select the currency.
Problem is when I press 'calculate' RaisedButton(looking at the image might help) nothing appears on screen (Initially I thought there is problem with buttton but later ) I found out that after pressing RaisedButton if I selected any item from dropdown then answer appears why is this happening, I have set an inital value as _selected = 'Rupee' am I doing something wrong?.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Simple Intrest Calculator',
home: MyHomePage(),
theme: ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.indigo,
accentColor: Colors.indigoAccent,
),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
var _currencies = ['Rupee', 'Dollar', 'Pound'];
final _minPadding = 5.0;
var _selected = 'Rupee';
TextEditingController principalCntr = TextEditingController();
TextEditingController roiCntr = TextEditingController();
TextEditingController termCntr = TextEditingController();
String _amount = '0';
#override
Widget build(BuildContext context) {
TextStyle styles = Theme.of(context).textTheme.headline6;
return Scaffold(
//resizeToAvoidBottomPadding: false,
appBar: AppBar(
title: Text('S.I Calculator'),
centerTitle: true,
),
body: Container(
margin: EdgeInsets.symmetric(vertical: 0, horizontal: _minPadding * 2),
child: ListView(
children: [
getImg(),
Padding(
padding: const EdgeInsets.symmetric(vertical: 5),
child: TextField(
controller: principalCntr,
keyboardType: TextInputType.number,
style: styles,
decoration: InputDecoration(
labelText: 'Principal',
hintText: 'Enter principal amount',
labelStyle: styles,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
),
),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 5),
child: TextField(
controller: roiCntr,
keyboardType: TextInputType.number,
style: styles,
decoration: InputDecoration(
labelText: 'Intrest',
hintText: 'Enter intrest rate',
labelStyle: styles,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: termCntr,
keyboardType: TextInputType.number,
style: styles,
decoration: InputDecoration(
labelText: 'Time',
hintText: 'Time in years',
labelStyle: styles,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
),
),
),
),
SizedBox(width: 50,),
Expanded(
child: DropdownButton(
value: _selected,
onChanged: (newVal) {
setState(() {
_selected = newVal;
});
},
items: _currencies.map((selectedVal) {
return DropdownMenuItem(
value: selectedVal,
child: Text(selectedVal),
);
}).toList(),
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: RaisedButton(
color: Theme.of(context).accentColor,
textColor: Theme.of(context).primaryColor,
child: Text('Calculate'),
onPressed: (){
_amount = _calculateReturns();
},
),
),
SizedBox(width: 20),
Expanded(
child: RaisedButton(
color: Theme.of(context).primaryColorDark,
textColor: Theme.of(context).primaryColorLight,
child: Text('Clear', style: TextStyle(fontSize: 20,),),
onPressed: (){
debugPrint('pressed');
},
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(_amount, style: styles,),
),
],
),
),
);
}
String _calculateReturns(){
double principal = double.parse(principalCntr.text);
double roi = double.parse(roiCntr.text);
double year = double.parse(termCntr.text);
double sI = principal + (principal*roi*year)/100;
String res = 'After $year years, you get $sI';
return res;
}
Widget getImg() {
AssetImage img = AssetImage('images/money.jpg');
Image image = Image(image: img, width: 125, height: 125);
return Container(
child: image,
margin: EdgeInsets.all(_minPadding * 10),
);
}
}
This is after i click Raised Button
This is after i select an item from dropdown but do not click on the button again:
Code walkthrough:
made a list of _currencies.
added textinput fields dropdown button and two raised buttons.
when calculate button is pressed _calculateReturns() is called which returns a value and stores it in _amount
Output is just a Text widget.
you forgot to update the screen when pressing on the button, remember every time you need to change the content of the page or update it you have to call the method :
setState(() {
// code here for values to be updated
});
so in your onPressed function of Raised button you have to add it like that :
onPressed: (){
_amount = _calculateReturns();
setState(() { });
}

Flutter textfield onChanged don't work when textfield bring value from controller

I'm working on flutter project and came across a problem. the textfield supposed to take a value from controller which work perfectly but onChanged function wont work. However it is not working.i must retype value to show results .
how can i get result from onchanged when my textfield brings the value ?
code:
// search function that call api
class _SearchPageTState extends State<SearchPageT> {
GlobalState _store = GlobalState.instance;
List<dynamic> searchResults = [];
searchT(value) async {
SearchServicet.searchApiT(value).then((responseBody) {
List<dynamic> data = jsonDecode(responseBody);
setState(() {
data.forEach((value) {
searchResults.add(value);
});
});
});
}
#override
///////
//code textfield search onchanged
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
centerTitle: true,
),
body: ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(10.0),
child: TextField(
autofocus: true,
controller: TextEditingController()
..text = '${_store.get('num')}',
onChanged: (value) {
searchResults.clear();
searchCodeighniterT(value);
},
textAlign: TextAlign.center,
decoration: InputDecoration(
contentPadding: EdgeInsets.only(left: 25.0),
labelText: 'number',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(4.0),
),
suffixIcon: IconButton(
icon: Icon(Icons.search),
onPressed: null,
),
),
),
),
SizedBox(
height: 10.0,
),
ListView.builder(
physics: ScrollPhysics(),
shrinkWrap: true,
itemCount: searchResults.length,
itemBuilder: (BuildContext context, int index) {
return buildResultCard(context, searchResults[index]);
},
),
],
),
),
);
}
//here where shows the result
Widget buildResultCard(BuildContext context, data) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
new Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/bgwlgo.png"), fit: BoxFit.cover),
),
margin: EdgeInsets.all(5.0),
child: Column(
children: <Widget>[
new Card(
child: ListTile(
title: Text(
"DATE:",
),
subtitle: Text(
data['DATETIME'].toString(),
),
),
),
new Card(
child: ListTile(
title: Text(
"TRAITEMENT:",
),
subtitle: Text(
data['TRAITEMENT_DETAIL'].toString()
),
),
),
new Padding(
padding: EdgeInsets.all(9.0),
),
],
),
),
Divider(
color: Colors.black,
)
],
),
);
}
As discussed and understood in the comments, here are a couple of possible solutions for the issue.
If you are using a stateful Widget and need a controller for your TextFormField, you can use it to set the text on the TextFormField. Otherwise, you can just use the initialValue property:
class TextFieldIssue64061076 extends StatelessWidget {
final TextEditingController _textEditingController = TextEditingController();
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children:[
Text('Page 1'),
TextFormField(
controller: _textEditingController,
),
FlatButton(
child: Text('Submit'),
onPressed: () => Navigator.of(context).push(MaterialPageRoute(
builder: (context) {
return SecondPage64061076(text: _textEditingController.text);
}
)),
),
],
);
}
}
class SecondPage64061076 extends StatefulWidget {
final String text;
SecondPage64061076({
this.text
});
#override
_SecondPage64061076State createState() => _SecondPage64061076State();
}
class _SecondPage64061076State extends State<SecondPage64061076> {
final TextEditingController _textEditingController = TextEditingController();
#override
void initState() {
// You can either use a text controller to set the text on the text field
// or the initialValue below
if(widget.text != null && widget.text != ''){
_textEditingController.text = widget.text;
methodToCallOnChanged(widget.text);
}else{
_textEditingController.text = '';
}
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Page 2'),
TextFormField(
controller: _textEditingController,
onChanged: (value) => methodToCallOnChanged(value),
// As mentioned you could just use the initial value, it you don't need
// a Stateful Widget
// initialValue: widget.text ?? '',
),
]
),
);
}
void methodToCallOnChanged(data){
print('I was called onChange or when the view opened and there was data');
}
}
Widget build(BuildContext context) {
bool isRecording = false;
bool isShowSendButton = false;
/// make sure textcontroller and any variabloes or booleans are not defined
///in the build method
}
You can't be using the constructor of the TextEditingController and assign it to the controller.
The controller of the TextField only takes the variable assigned to the TextEditingController. Check the following code.
controller:theNameOfYourController
Expanded(
flex: 8,
child: Padding(
padding: const EdgeInsets.only(left: 8.0, right: 10),
child: TextFormField(
onChanged: (value){
messageFieldController.text=value;
},
//controller: messageFieldController,
minLines: 1,
maxLines: 2,
textCapitalization: TextCapitalization.sentences,
keyboardType: TextInputType.multiline,
decoration: InputDecoration(
prefixIcon: IconButton(
onPressed: () {},
icon: const Icon(Icons.add, color: Colors.blue),
),
suffixIcon: processing == true
? const CircularProgressIndicator()
: IconButton(
onPressed: () {
try {
/*for (int i = 0;
i < widget.selectedMembers.length;
i++) {
sendMessage(
widget.selectedMembers[i].number);
}*/
for (int i = 0;
i < widget.selectedGroups.length;
i++) {
if (widget.selectedGroups.isNotEmpty) {
sendMessageToGroup(
widget.selectedGroups[i].id,
widget.selectedGroups[i].groupName);
}
}
} catch (err) {
Fluttertoast.showToast(
msg: 'Unable to send Message');
setState(() {
processing = false;
});
}
},
icon:
const Icon(Icons.send, color: Colors.blue),
),
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(50),
),
),
),
),
),
)