Get value from textFormField within a ListView - flutter

I've a ListView in my flutter project, in which I have 2 TextFormFields. I want the get the value whatever user has typed in from the TextFormField and print it(for now).
I've checked following link - Flutter : Textfield in ListView.builder and tried to get the value.
Following is my code -
class _OrderBookingState extends State<OrderBooking> {
#override
Widget build(BuildContext context) {
TextEditingController controller = new TextEditingController();
List<TextEditingController> _textFieldRateControllers = new List();
List<TextEditingController> _textFieldQtyControllers = new List();
return Scaffold(
appBar: AppBar(
title: Center(child: Text(widget.shop.shopName)),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
child: StreamBuilder<List<ProductModel>>(
stream: DatabaseService().productList,
builder: (context,snapshot){
if(snapshot.hasData){
return Flexible(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (context, index){
_textFieldRateControllers[index].text = "5";
_textFieldQtyControllers[index].text = "5";
_textFieldQtyControllers.add(new TextEditingController());
_textFieldRateControllers.add(new TextEditingController());
return Padding(
padding: EdgeInsets.only(top: 8.0),
child: Card(
margin: EdgeInsets.fromLTRB(10.0, 6.0, 10.0, 0.0),
child: ListTile(
leading: CircleAvatar(
radius: 25.0,
backgroundColor: Colors.deepOrangeAccent,
),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
width: 175,
child: Text(snapshot.data[index].productName,),
),
// Expanded(child: Container(
// width: 10,
// child: Center(child: Text(snapshot.data[index].productName,)))),
SizedBox(width: 5,),
Expanded(child: Container(
width: 10,
child: TextFormField(
controller: _textFieldRateControllers[index],
initialValue: snapshot.data[index].rate,textAlign: TextAlign.center,
),
),
),
SizedBox(width: 5,),
Expanded(child: TextFormField(
controller: _textFieldQtyControllers[index],
initialValue: "0",textAlign: TextAlign.center,)
)
],
),
subtitle: Text('MRP ' + snapshot.data[index].mrp),
),
),
);
}
),
);
}else{
return Loading();
}
}
),
),
Container(
margin: EdgeInsets.fromLTRB(10.0, 6.0, 10.0, 0.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Total Value: 0/-",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold,backgroundColor: Colors.greenAccent)
),
RaisedButton(
child: Text("Save",style: TextStyle(fontSize: 18.0),),
color: Colors.green,
textColor: Colors.white,
highlightColor: Colors.lightGreenAccent,
onPressed: (){
print(_textFieldQtyControllers[1].text);
},
)
],
),
)
],
),
);
}
}
I'm getting below error -
RangeError (index): Invalid value: Valid value range is empty: 0
Please let me know how to solve this.

NEW UPDATE
You need to the remove the initalValue argument from the TextField:
Expanded(child: TextFormField(
controller: _textFieldQtyControllers[index],
initialValue: "0", //REMOVE THIS LINE
textAlign: TextAlign.center,)
)
And you have the wrong order of actions, it must be:
Set add the TextEditingController to your list with
_textFieldRateControllers.add(new TextEditingController());
_textFieldQtyControllers.add(new TextEditingController());
Set the controller text to your initialValue:
_textFieldRateControllers[index].text = snapshot.data[index].rate.toString();
_textFieldQtyControllers[index].text = "0";
OLD
To solve your error, remove the initialValue and instead set the
//set this after
_textFieldRateControllers[index].text = //your Initial data
_textFieldQtyControllers[index].text = //your Initial data
I think you did not set the List properly, as a TextEditingController needs to be created like this:
TextEditingController controller = new TextEditingController();
So then in your ListView, call this in the builder:
_textFieldRateControllers.add(new TextEditingController());
_textFieldQtyControllers.add(new TextEditingController());
This creates the controller properly with a constructor

late List<TextEditingController> txtDataNascDogs;
late List<FocusNode> _dataNascFocuss;
#override
void initState() {
txtDataNascDogs = List<TextEditingController>.generate(
Get.find<AgendamentoVacinaController>().listDogMenorIdade.length,
(index) => TextEditingController(text: ""));
_dataNascFocuss = List<FocusNode>.generate(
Get.find<AgendamentoVacinaController>().listDogMenorIdade.length,
(index) => FocusNode());
super.initState();
}

Related

not able to return elements with nested gridview builder - fluttter

my case is that I am retrieving values images and text for challenges (like products ...etc), the challenges should appear one by one vertically first the image appears then the text appears over the image in the centre so I used stack and padding and I was able to retrieve one challenge information only, now I want to retrieve all challenges vertically using gridview builder, so I have did this :
Widget build(BuildContext context) {
return GridView.builder(
scrollDirection: Axis.vertical,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: _challenges.length),
itemBuilder: (_, index) {
return InkWell(
onTap: () {},
child: Stack(
children: [
Padding(
padding: EdgeInsets.all(10.0),
child: Center(
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: Image(
image:
NetworkImage(_challenges[index]["image-path"][0]),
fit: BoxFit.cover,
height: 150,
width: 350,
opacity: AlwaysStoppedAnimation(.4),
),
),
),
),
Padding(
padding: const EdgeInsets.all(60.0),
child: Center(
child: Text(
"${_challenges[index]["name"]}\n${_challenges[index]["date"]}",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
),
],
),
);
});
every time i hot reload the app i get this error:
'package:flutter/src/rendering/sliver_grid.dart': Failed assertion: line 319 pos 15: 'crossAxisCount != null && crossAxisCount > 0': is not true.
and in just in case this is how i retrieved the data from Firestore:
List _challenges = [];
fetchChallengeData() async {
var _fireStoreInstance = FirebaseFirestore.instance;
QuerySnapshot qn = await _fireStoreInstance.collection("challenges").get();
setState(() {
for (int i = 0; i < qn.docs.length; i++) {
_challenges.add({
"image-path": qn.docs[i]["image-path"],
"name": qn.docs[i]["name"],
"date": qn.docs[i]["date"],
});
}
});
}
#override
void initState() {
fetchChallengeData();
super.initState();
}
the home screen where i use to display the element looks like:
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.purple,
title: Text(
"أتحداك",
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
centerTitle: true,
),
body: SingleChildScrollView(
child: Column(
children: [
AdsBanner(),
SizedBox(
height: 50,
),
Directionality(
textDirection: TextDirection.rtl,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Text(
"التحديات",
style: TextStyle(fontSize: 20),
),
Text(
" (إضغط على التحدي للإشتراك به)",
style: TextStyle(fontSize: 15),
)
],
),
),
),
ChallengeCard(),
],
),
),
endDrawer: NavigationDrawer());
so basically the parent is a column and the parent of the column is singleChildScrollView,
any help I would be grateful, Thanks.
We are getting data from future fetchChallengeData, So it will be null initially, Try returning another widget on null or empty cases
Widget build(BuildContext context) {
return _challenges!=null && _challenges.isNotEmpty? GridView.builder(...): SizedBox.shrink();
Though _challenges.isNotEmpty enough while we've List _challenges = [];
I think we are seeking somthing like this
Widget myGridView() {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4, //number of items on single Row
),
itemCount: _challenges.length, // number of item will render
itemBuilder: (context, index) => Text("Your item Builder"),
);
}
Widget placement
body: Column(
children: [
AdsBanner(),
SizedBox(
height: 50,
),
Directionality(
textDirection: TextDirection.rtl,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Text(
"التحديات",
style: TextStyle(fontSize: 20),
),
Text(
" (إضغط على التحدي للإشتراك به)",
style: TextStyle(fontSize: 15),
)
],
),
),
),
Expanded(child: ChallengeCard()),
],
),

Flutter: Make list scrollable

this is a typical question that might be considered as low quality but I have been on this for about two hours, and I am just trying to understand this piece of code better, so instead of just telling me how to fix, could you please also explain a bit what is happening. I am sure that for someone more experienced that me, should be very easy to spot.
I am trying to make a scrollable list, and draw each row of the list, and be able to click in each row item. But my app draws all the items but I am only able to see some of the items, as much as the screen allows, which means it is not scrollable.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Some App Page'),
),
body: ListView(
children: <Widget>[
Stack(
alignment: const Alignment(1.0, 1.0),
children: <Widget>[
TextField(
controller: cityController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: 'Enter city...'),
),
TextButton(
onPressed: () {
cityController.clear();
},
child: const Icon(Icons.clear),
),
],
),
ElevatedButton(
onPressed: () {
_futureTime = fetchTimes(int.parse(cityController.text));
if (cityController.text.isNotEmpty) {
setState(() {
cityController.clear(); // Clear value
}); // clear the textField
FocusScope.of(context)
.requestFocus(FocusNode()); // hide the keyboard
}
},
child: const Text('Get City', style: TextStyle(fontSize: 20)),
),
Column(
children: <Widget>[
Center(
child: FutureBuilder<Times>(
future: _futureTime,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const CircularProgressIndicator();
}
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return myTimeCard( date, index);
},
itemCount: data == null ? 0 : data.length,
);
},
),
),
],
),
],
),
);
}
Widget myTimeCard(String date, int index) {
return InkWell(
onTap: () {
// Navigate to the next page & pass data.
print("tapped, -> " + index.toString()); // for debugging purpose!
},
child: Stack(
children: <Widget>[
Opacity(
opacity: 1,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 16.0),
child: Text(
index.toString(),
style: const TextStyle(
color: Colors.black,
fontSize: 22.0,
fontWeight: FontWeight.bold),
),
),
],
)
],
)
],
),
);
}
You are using two ListView s nested inside each other. In such cases you may need to let the Flutter know which ListView is the primary one. So, there is a property called primary. Try to set primary to false for the inner Listview.
return ListView.builder(
primary: false,
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return myTimeCard( date, index);
},
itemCount: data == null ? 0 : data.length,
);
The code you shared does not compile because I do not have additional context, so I had to spend some time to be able to make it compile, please make sure to provide a compilable code in the future.
the problem you're facing is because the main ListView is taking control of the scroll, to see the effect try scrolling by holding the screen from the button Get City.
There are many ways to solve this problem, depending on your goal, do you want to make the whole screen scrollable, or just the data list
Way 1. Make the whole screen scrollable:
by keeping the control of the scroll in the main ListView, and making all the descending widgets non-scrollable, which in your case, by making the widget that wraps the data a Column instead of ListView:
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final TextEditingController cityController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Some App Page'),
),
body: ListView(
children: <Widget>[
Stack(
alignment: const Alignment(1.0, 1.0),
children: <Widget>[
TextField(
controller: cityController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: 'Enter city...'),
),
TextButton(
onPressed: () {
cityController.clear();
},
child: const Icon(Icons.clear),
),
],
),
ElevatedButton(
onPressed: () {
_futureTime = fetchTimes(int.parse(cityController.text));
if (cityController.text.isNotEmpty) {
setState(() {
cityController.clear(); // Clear value
}); // clear the textField
FocusScope.of(context)
.requestFocus(FocusNode()); // hide the keyboard
}
},
child: const Text('Get City', style: TextStyle(fontSize: 20)),
),
Column(
children: <Widget>[
Center(
child: FutureBuilder<Times>(
future: _futureTime,
builder: (context, snapshot) {
// if (!snapshot.hasData) {
// return const CircularProgressIndicator();
// }
final data =
// snapshot.data;
List.generate(50, (index) => index.toString());
return Column(
children: [
for (int i = 0; i < data.length; i++)
myTimeCard(data[i], i)
],
);
},
),
),
],
),
],
),
);
}
Widget myTimeCard(String date, int index) {
return InkWell(
onTap: () {
// Navigate to the next page & pass data.
print("tapped, -> " + index.toString()); // for debugging purpose!
},
child: Stack(
children: <Widget>[
Opacity(
opacity: 1,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 16.0),
child: Text(
index.toString(),
style: const TextStyle(
color: Colors.black,
fontSize: 22.0,
fontWeight: FontWeight.bold),
),
),
],
)
],
)
],
),
);
}
}
Way 2. make the non-data widgets non-scrollable, and keep the scroll control in the data widget:
can be done by converting the main ListView to a non-scrollable Widget (in your case Column), and wrapping the data list in Expanded widget, so it takes all the space it can have (for more info about Expanded):
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final TextEditingController cityController = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Some App Page'),
),
body: Column(
children: <Widget>[
Stack(
alignment: const Alignment(1.0, 1.0),
children: <Widget>[
TextField(
controller: cityController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: 'Enter city...'),
),
TextButton(
onPressed: () {
cityController.clear();
},
child: const Icon(Icons.clear),
),
],
),
ElevatedButton(
onPressed: () {
_futureTime = fetchTimes(int.parse(cityController.text));
if (cityController.text.isNotEmpty) {
setState(() {
cityController.clear(); // Clear value
}); // clear the textField
FocusScope.of(context)
.requestFocus(FocusNode()); // hide the keyboard
}
},
child: const Text('Get City', style: TextStyle(fontSize: 20)),
),
FutureBuilder<Times>(
future: _futureTime,
builder: (context, snapshot) {
// if (!snapshot.hasData) {
// return const CircularProgressIndicator();
// }
final data =
// snapshot.data;
List.generate(50, (index) => index.toString());
return Expanded(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return myTimeCard(date, index);
},
itemCount: data == null ? 0 : data.length,
),
);
},
),
],
),
);
}
Widget myTimeCard(String date, int index) {
return InkWell(
onTap: () {
// Navigate to the next page & pass data.
print("tapped, -> " + index.toString()); // for debugging purpose!
},
child: Stack(
children: <Widget>[
Opacity(
opacity: 1,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 16.0),
child: Text(
index.toString(),
style: const TextStyle(
color: Colors.black,
fontSize: 22.0,
fontWeight: FontWeight.bold),
),
),
],
)
],
)
],
),
);
}
}
The issue is coming because we have two scrollable ListView. While both of them are scrollable, while scrolling when the inner ListView it gets focused and parent become unfocus and scroll event only effect on inner ListView and you can't rollback to parent ListView, A simple solution will be using NeverScrollableScrollPhysics on inner
ListView.builder.
child: ListView.builder(
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,
singleChildScrollView(
child: ListView.builder(
sinkwrap:true,
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.vertical,)
)
Simple and Easy

Multiply value of textformfield in Listview and get the sum of it

I have two textformfields in my listview. I want to get the value from each of them, multiply for each index and ultimately get the total value. It's more like an invoice. This will be done onChange of the textformfields. I have the following code which does not return the correct output.
class _OrderBookingState extends State<OrderBooking> {
#override
Widget build(BuildContext context) {
TextEditingController controller = new TextEditingController();
List<TextEditingController> _textFieldRateControllers = new List();
List<TextEditingController> _textFieldQtyControllers = new List();
var productCount = 0;
return Scaffold(
appBar: AppBar(
title: Center(child: Text(widget.shop.shopName)),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
child: StreamBuilder<List<ProductModel>>(
stream: DatabaseService().productList,
builder: (context,snapshot){
productCount = snapshot.data.length;
if(snapshot.hasData){
return Flexible(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (context, index){
_textFieldQtyControllers.add(new TextEditingController());
_textFieldRateControllers.add(new TextEditingController());
_textFieldRateControllers[index].text = snapshot.data[index].rate;
_textFieldQtyControllers[index].text = "0";
countTotal(){
var totalSum = 0.0;
_textFieldQtyControllers.forEach((element) {
var rateDouble = double.parse(_textFieldRateControllers[index].text);
var qtyDouble = double.parse(_textFieldQtyControllers[index].text);
var multiple = rateDouble*qtyDouble;
totalSum += multiple;
//calculateTotal(element, _textFieldRateControllers[index].text, _textFieldQtyControllers[index].text);
}
);
print("Total is $totalSum" );
}
return Padding(
padding: EdgeInsets.only(top: 8.0),
child: Card(
margin: EdgeInsets.fromLTRB(10.0, 6.0, 10.0, 0.0),
child: ListTile(
leading: CircleAvatar(
radius: 25.0,
backgroundColor: Colors.deepOrangeAccent,
),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
width: 175,
child: Text(snapshot.data[index].productName,),
),
// Expanded(child: Container(
// width: 10,
// child: Center(child: Text(snapshot.data[index].productName,)))),
SizedBox(width: 5,),
Expanded(child: Container(
width: 10,
child: TextFormField(
controller: _textFieldRateControllers[index],
textAlign: TextAlign.center,
onChanged: (text){
countTotal();
},
//onChanged: (text){calculateTotal(productCount, _textFieldRateControllers[index].text, _textFieldQtyControllers[index].text);},
),
),
),
SizedBox(width: 5,),
Expanded(child: TextFormField(
controller: _textFieldQtyControllers[index],
textAlign: TextAlign.center,
onChanged: (text){
countTotal();
//calculateTotal(productCount, _textFieldRateControllers[index].text, _textFieldQtyControllers[index].text);
},
)
)
],
),
subtitle: Text('MRP ' + snapshot.data[index].mrp),
),
),
);
}
),
);
}else{
return Loading();
}
}
),
),
Container(
margin: EdgeInsets.fromLTRB(10.0, 6.0, 10.0, 0.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Total Value: 0/-",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold,backgroundColor: Colors.greenAccent)
),
RaisedButton(
child: Text("Save",style: TextStyle(fontSize: 18.0),),
color: Colors.green,
textColor: Colors.white,
highlightColor: Colors.lightGreenAccent,
onPressed: (){
//print(_textFieldQtyControllers[1].text);
},
)
],
),
)
],
),
);
}
}
As per the image it should return (260+85+67 = 412) which I'm not getting.Please let me know how to achieve this.
The reason is you are assigning qty as zero in itembuilder of your listview:-
_textFieldQtyControllers[index].text = "0";
So replace it with 10 as per your image:-
_textFieldQtyControllers[index].text = "10";

How to change place of children widgets in Column?

I need to change the place of the widget in my UI. But I could not achieve it.
I tried this code But it does not work for me. If someone knows how to do it please help.
Change Place of BankCard Widget to Another BankCard Widget, or change the place of any widgets in a Column.
Below you can find code that I tried:
Widget nonNullBody(List<GetConversionCards> cards) {
_column=Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
"fromSum".tr(),
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.w700),
textAlign: TextAlign.left,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: BankCard(
card: Bank.CreditCardModel.fromUzCard(
cards[bloc.selectedIndex.value])),
),
IconButton(
icon: Icon(Icons.sync),
onPressed: () {
_key.currentState.setState(() {
Widget t=_column.children[0];
_column.children[0]=_column.children[3];
_column.children[3]=t;
});
},
),
Text("toVisa".tr(),
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w700),
textAlign: TextAlign.left),
Padding(
padding: const EdgeInsets.all(8.0),
child: BankCard(
card: Bank.CreditCardModel.fromVisaCard(
cards[bloc.selectedIndex.value])),
),
],);
bloc.tokenCardUzs = cards[0].uzsCardId;
final size = MediaQuery.of(context).size;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: SingleChildScrollView(
child: Container(
height: size.height - appBar().preferredSize.height + 5,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
height: 30,
child: ValueListenableBuilder(
valueListenable: bloc.selectedIndex,
builder: (context, v, w) {
return ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: cards.length,
itemBuilder: (context, index) {
return Container(
width: 8.0,
height: 8.0,
margin: EdgeInsets.symmetric(
vertical: 12.0, horizontal: 2.0),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: bloc.selectedIndex.value == index
? Color.fromRGBO(0, 0, 0, 0.9)
: Color.fromRGBO(0, 0, 0, 0.4)),
);
});
}),
),
Flexible(
fit: FlexFit.loose,
flex: 5,
child: PageView.builder(
scrollDirection: Axis.horizontal,
itemCount: cards.length,
onPageChanged: (_) {
bloc.tokenCardUzs = cards[_].uzsCardId;
bloc.selectedIndex.value = _;
},
itemBuilder: (BuildContext context, int index) {
return StatefulBuilder(
key: _key,
builder: (BuildContext context,
void Function(void Function()) state) {
return _column; );
}),
),
Flexible(
child: TextFieldWidget(
controller: bloc.amountFieldController,
iconData: Icons.monetization_on,
validator: null,
hintText: "enterAmount".tr(),
labelText: "dollarCurrency".tr(),
),
),
ConfirmButton(
text: 'next'.tr(),
onPressed: () {
showPopUp(context, () async {
Navigator.of(context, rootNavigator: true).pop();
waitTransactionWidget(context);
int usd =
(double.parse(bloc.amountFieldController.text) * 100)
.toInt();
bool result = await Repository.getInstance()
.convUzsUsd(bloc.tokenCardUzs, usd);
print("result conv $result");
Navigator.of(context, rootNavigator: true).pop();
Navigator.pushReplacement(
context,
PageTransition(
child: MyHomePage(),
type: PageTransitionType.fade));
},
title: Text("wouldYouLikeToExchange".tr()),
subtitle: Text("${bloc.amountFieldController.text} " +
"dollarCurrency".tr()));
},
),
],
),
),
),
);
}
I recommend you create a list that contains widgets then assign it to the childrens parameters of Column. So when you change something about the list it will change the column as well.
like this :
List<Widget> list = new List();
#override
Widget build(BuildContext context) {
Column(
children: list,
);
}
adjustWidgetList() {
setState(() {
list.add(Text("lorem ipsum"));
list.add(Text("dolar sit amet."));
.
.
.
list.remove(0);
});
}
But don't forget to make your changes inside of setState.

I want to delete selected data from the list using the delete button in action bar

I'm new to flutter and I want to delete the selected values from the
list,but I don't know how to delete selected Items,can anyone help?
I have taken icon button in Appbar and I tried to setState in it by
using the .removelast() command,but I want to select the Item then
delete it.
Code :
class DemoPage extends State<MyHomePage> {
TextEditingController Controller = TextEditingController();
List<String> msg = List();
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Demo_App'),
actions: <Widget>[
IconButton(icon: Icon(Icons.delete),
onPressed: (){
setState(() {
msg.removeLast();
});
}),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
alignment: Alignment.topLeft,
margin: EdgeInsets.only(right: 150.0,top: 10.0,left: 8.0),
child:TextField(
controller: Controller,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'please enter your name',
),
),
),
Container(
alignment: Alignment.topRight,
margin: EdgeInsets.only(left: 250.0,right: 10.0),
child: RaisedButton(
onPressed: () {
setState(() {
msg.add(Controller.text);
Controller.clear();
});
},
child: Text('Add'),
),
),
Expanded(
flex: 2,
child: Container(
child: Card(
margin: EdgeInsets.all(8.0),
child: ListView.builder(
itemCount: msg.length,
itemBuilder: (context, index){
if(index.isInfinite){
return Divider();
}
return ListTile(
title: Text(msg[index]),
);
},),
),
)),
],
),
);
}
}
I want to select the data and then delete it using the icon Button in
the AppBar.
Lets assume you want to select your items by a single click.
Take a separate a list indexList and each time you select an item, you store the clicked index into indexList.
Then upon clicking delete button run a loop on indexList and remove items from your itemList using the stored indexes.
clean indexList
update your state
class DemoPage extends State<MyHomePage> {
TextEditingController Controller = TextEditingController();
List<String> msg = List();
List<int> selectedItems = List();
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('Demo_App'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.delete),
onPressed: () {
setState(() {
msg.removeLast();
});
}),
],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
alignment: Alignment.topLeft,
margin: EdgeInsets.only(right: 150.0, top: 10.0, left: 8.0),
child: TextField(
controller: Controller,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'please enter your name',
),
),
),
Container(
alignment: Alignment.topRight,
margin: EdgeInsets.only(left: 250.0, right: 10.0),
child: RaisedButton(
onPressed: () {
setState(() {
msg.add(Controller.text);
Controller.clear();
});
},
child: Text('Add'),
),
),
Expanded(
flex: 2,
child: Container(
child: Card(
margin: EdgeInsets.all(8.0),
child: ListView.builder(
itemCount: msg.length,
itemBuilder: (context, index) {
return new GestureDetector(
onLongPress: () {
if(selectedItems.contains(index))
selectedItems.remove(index);
else
selectedItems.add(index);
},
onTap: () {
if(selectedItems.contains(index))
selectedItems.remove(index);
else
selectedItems.add(index);
},
child: index.isInfinite
? Divider()
: ListTile(
title: Text(msg[index]),
));
}),
),
)),
],
),
);
}
void _deleteItems(){ // call _deleteItems() on clicking delete button
setState(() {
//set your state
for (final index in selectedItems)
msg.removeAt(index);
selectedItems.clear();
});
}
}