How can I remove the icon when the validation is null in flutter? - list

I have a function that receives a list in the function parameter and I am displaying that list.
I have a validation in the Text, when it is null it shows me a message that says "no data" or otherwise it shows me the value of the list.
What I want to remove the cancel icon when it is null and only appear when I have a value to display.
Help would be greatly appreciated.
Code and Image ::
Widget SfuluilderSuggestions(List <SDM> historialMenuPrincipal){
return Container(
child:StatefulBuilder(
builder:(context,setState)
{
return Container(
child: ListView.builder(
itemCount: historialMenuPrincipal.length,
itemBuilder: (context,i)
{
contentPadding: EdgeInsets.symmetric(vertical: 12,horizontal: 16);
leading:CircleAvatar(
radius: 32,
backgroundImage: NetworkImage(
"https://2.bp.blogspot.com/-3ZzNt8ZjQk/WR9W4Fn4II/AAAAAAAJw/_inTVynhS6V75IZ-461-pda7WyrTStwCEw/s1600/A.jpg"),
);
return
ListTile(
title: Text(historialMenuPrincipal[i] == null ? "no data":historialMenuPrincipal[i].email ),
trailing: IconButton(
icon: Icon(Icons.cancel,color: Colors.black,),
onPressed: () {
setState(() {
historialMenuPrincipal.remove(historialMenuPrincipal[i]);
});
},
),
);
}
),
);
}
)
);
}

You can check if the text is null -
trailing: Text(historialMenuPrincipal[i] != null ? IconButton(
icon: Icon(Icons.cancel,color: Colors.black,),
onPressed: () {
setState(() {
historialMenuPrincipal.remove(historialMenuPrincipal[i]);
});
},
) : Padding(padding:EdgeInsets.zero),

While historialMenuPrincipal contains data, you can remove only when data is available. You can pass null on trailing.
trailing:
historialMenuPrincipal.contains(historialMenuPrincipal[i])
? IconButton(...)
: null
If you want to skip the generating ListTile, you can check on return level and provide SizedBox or better filter data while generating the list.

Related

Flutter property values of a Map all treated as strings

I have a list like this a = [{'one': 'one', 'two': null, 'three': [{'four': 'four'}]}]
I send it to a function to use it in a post request which in the body should receive a Map, so what I did was this to a[0], the problem is that I get this error The getter 'length' was called on null
I start to review and it treats all the property values as if they were Strings, even the nested list 'three': [{'four': 'four'}], I have tried to send the post in this way http.post (url, body: (recurrence [0] as Map)) but it has not worked, it always gives me the same error, even if in the body I put the properties by hand in the body: {'new property': a [0] [' tres']}, how should one act to solve this problem? Thank you very much for your help
Code:
void _ordersGet() async {
await http.get(url).then((value) {
setState(() {
orders = jsonDecode(value.body);
}
}
orders is sent to a new widget: orderList(orders)
orderList is a listView
ListView.builder(
shrinkWrap: true,
primary: false,
itemCount: orders.length,
itemBuilder: (orders, index) {
return return Card(
elevation: 5,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(orders[index]['facts']),
SizedBox(
width: 4,
),
Text('Cantidad : '),
Text(orders[index]['ITEMS'][0]['jeans']),
SizedBox(
width: 4,
),
IconButton(
onPressed: () => _reorderData(context, orders[index]),
icon: Icon(
Icons.replay_outlined,
color: Theme.of(context).accentColor,
)),
],
),
);
},
);
_reorderData is a function that make a get request, the info in shipped to ReorderModal
ReorderModal it only shows the information and has a button
void _reorderData(BuildContext ctx, order) async {
var data;
var url = 'serverAddress/${order['facts']}';
await http.get(url).then((value) {
data = jsonDecode(value.body);
data[0]['CORPORATION'] = order['corporation'];
showModalBottomSheet(
context: ctx,
builder: (_) {
return ReorderModal(data);
});
}).catchError((onError) {});
}
class ReorderModal extends StatelessWidget {
final List data;
ReorderModal(this.data);
void orderSend(orderInfo) async {
var url = 'serverAddress';
await http.post(url, body: orderInfo[0]).then((value) {
print(jsonDecode(value.body));
}).catchError((onError) {
print(onError);
});
}
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(10),
child: Column(children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Column(
children: [
ElevatedButton(
onPressed: () {
orderSend(data);
//print(data);
},
child: Text('ONE Click'))
]),
);
}
}
when i press the ONE Click button execute the function orderSend, orderSend make a post request and the problem described above
This is the simplified code, I know it must be something very simple, but it is giving me a lot of work to solve

Flutter-Dart List-Map get item number or text where i clicked?

I wanna get a String or Map Number int if I clicked on List. I wanna forward to another Function. Like this,
I got a List,
List <String> konulistesi = <String> ["Max","Adam","Anna","Sophie","Alex",]
And if I click on the List example Adam, then it will print to number like : 1, or for Sophie print: 3,
body: SafeArea(
child:
ListView.separated(
padding: const EdgeInsets.all(8),
itemCount: konuListesi.length,
itemBuilder: (BuildContext context, int index) {
return Container(
height: 50,
color: Colors.green,
child: InkWell(child:
Center(child:
Text(konuListesi[index],style: TextStyle(color: Colors.black,fontWeight: FontWeight.w600,fontSize: 18),),),
onTap: ()=> {
print("Number of the Position or direkt Item"),
}),
);
},
separatorBuilder: (BuildContext context, int index) => const Divider(),
),
),
You should not use the arrow function for the onTap method of the InkWell widget. print(index) will give you the index of the array. print(index + 1) will give you the countable index of the array. The index of an array starts with 0 in Dart.
And, print(konuListesi[index]) will give you the selected item:
onTap: () {
print("Number of the Position or direkt Item");
print(index);
print(konuListesi[index]);
}),

create a item list in a cart with a list (Flutter Web)

I tried to create a list of items in an order cart. But it shows only the first item in the list....
Here is my code:
.......
class CartItem {
String name;
String quantity;
String price;
CartItem({
this.name,
this.quantity,
this.price,
});
}
List<CartItem> cartItem = [];
var _quantity = TextEditingController();
........
Widget cartList() {
if (cartItem.length != 0) {
for (var item in cartItem) {
return new Text('${item.name}');
}
}
return Text('Nothing in Cart');
}
.......
RaisedButton(
elevation: 1,
color: Colors.blueGrey,
onPressed: () {
showDialog(
context: context,
builder: (BuildContext contex) {
return AlertDialog(
content: Column(
children: [
Text('Your Order List'),
Container(
child: cartList(),
),
],
),
);
},
);
},
child: Text(
'Conferm Order',
textAlign: TextAlign.end,
),
),
I also tried with listview.builder but I have failed. It gives me some error. Something like "Assertion failed" or "Rendering" type error.
Widget cartList() {
if (cartItem.length != 0) {
return ListView.builder(
itemCount: cartItem.length,
itemBuilder: (context, index) {
return Text(cartItem[index].name);
},
);
}
return Text('Nothing in Cart');
}
this is the error when I try with Listiew.builder:
The following RenderObject was being processed when the exception was fired:
RenderIntrinsicWidth#3fbd2 relayoutBoundary=up6 NEEDS-LAYOUT NEEDS-PAINT
NEEDS-COMPOSITING-BITS-UPDATE:
creator: IntrinsicWidth ← Semantics ← DefaultTextStyle ← AnimatedDefaultTextStyle ←
_InkFeatures-[GlobalKey#eb4f8 ink renderer] ←
NotificationListener ←
CustomPaint ← _ShapeBorderPaint ← PhysicalShape ← _MaterialInterior ← Material ←
ConstrainedBox ←
⋯
parentData: (can use size)
constraints: BoxConstraints(280.0<=w<=711.0, 0.0<=h<=343.0)
size: MISSING
stepWidth: null
stepHeight: null
This RenderObject had the following descendants (showing up to depth 5):
child: RenderFlex#22eec NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
child 1: RenderPadding#42cc4 NEEDS-LAYOUT NEEDS-PAINT
NEEDS-COMPOSITING-BITS-UPDATE
child: RenderFlex#09e2b NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
child 1: RenderParagraph#afac8 NEEDS-LAYOUT NEEDS-PAINT
text: TextSpan
child 2: RenderRepaintBoundary#14459 NEEDS-LAYOUT NEEDS-PAINT
NEEDS-COMPOSITING-BITS-UPDATE
child: RenderCustomPaint#ddfde NEEDS-LAYOUT NEEDS-PAINT
NEEDS-COMPOSITING-BITS-UPDATE
And this:
Another exception was thrown: Assertion failed:
file:~flutter/packages/flutter/lib/src/rendering/mouse_tra
cking.dart:392:12
So first off, the moment you return in almost any programming language, you go out of the function. So you won't get a list but only a single Text widget.
And about the ListView.builder, you're missing the .name (if you want to show more things like price you have to use another widget or concatenate them into a single string since Text only accepts a String):
Widget cartList() {
if (cartItem.length != 0) {
return ListView.builder(
itemCount: cartItem.length,
itemBuilder: (context, index) {
return Text(cartItem[index].name);
},
);
}
return Text('Nothing in Cart');
}
Instead of Text widget you could potentially use ListTile which has placeholders for many Text widgets usually useful for lists.
Now for the layout error, the simplest fix would be to add height and width properties for the Container containing your cartList:
return AlertDialog(
content: Column(
children: [
Text('Your Order List'),
Container(
height: 300, // or any other number
width: 300, // or any other number
child: cartList(),
),
],
),
);

Create a switch list tile with separators in flutter

I am trying to create a list of switch tiles in flutter which have separators between the tiles.
I've tried doing this by using ListTile.divideTiles:
ListView(
children: ListTile.divideTiles(
context: context,
tiles: [
SwitchListTile(
secondary: Icon(Icons.signal_cellular_4_bar),
title: Text(
"First Tile",
),
value: var1,
onChanged: (bool value) {
setState(
() {
var1= value;
},
);
},
),
SwitchListTile(
secondary: Icon(Icons.swap_vert),
title: Text(
"Second Tile",
),
value: var2,
onChanged: (bool value) {
setState(
() {
var2= value;
},
);
},
),
],
),
),
But when I tried running the code I got the following error:
"type '_SyncIterable<Widget>' is not a subtype of type 'List<Widget>'"
Who do I create a list of switch tiles with separator?
Please try this.
Add .toList() to the end of your ListTile.divideTiles
ListTile.divideTiles(
// all your code
// all your code
// all your code
).toList()
Why don't you try ListView.separated ?
int _selectedIndex = 0;
return ListView.separated(
//Here's your separator
separatorBuilder: (BuildContext context, int index) {
return SizedBox(
height: 10, //Whatever spacing you want.
);
},
physics: BouncingScrollPhysics(),
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: 2, //How many tiles you want
padding: EdgeInsets.all(10),
itemBuilder: (BuildContext context, int index) {
return ClipRRect( //round up the edges for nicer look
borderRadius: BorderRadius.all(Radius.circular(5)),
//And here's your tile
child: SwitchListTile(
tileColor: Colors.grey[900],
selectedTileColor: Colors.black,
selected: index == _selectedIndex,
value: ... ,
onChanged: (v) {
...
},
title: Text('Tile #' + index.toString()),
subtitle: Text('-'),
),
);
},
);

Cannot map a list to a widget

I have a hardcoded list that I want to map it to a list of widgets. The code below shows squiggly lines with the error The return type 'List<ItemWidget>' isn't a 'Widget', as defined by anonymous closure.dart(return_of_invalid_type_from_closure).
.................MISSING CODE....................
ListView.builder(
itemBuilder: (context, index) => items.map((item) => ItemWidget(item: item)).toList();
)
..................MISSING CODE....................
class ItemWidget extends StatelessWidget{
final Item item;
ItemWidget({this.item});
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Expanded(
child: FittedBox(
fit: BoxFit.fill,
child: Image.asset(item.iconPath)
)
),
Padding(
padding: const EdgeInsets.only(top: 15.0),
child: Text(item.name),
)
],
);
}
}
EDIT:
This is the list of items, currently I hold just an item for testing purposes.
List<Item> items = [
Item(name: 'Medicines', iconPath: '$ICON_BASE_PATH/medicines.svg'),
];
If you have any idea please let me know, thanks!
The issues is using the ListView.builder, the builder function expects you to return one Widget at a time corresponding to the index provided. Use ListView directly instead.
Example:
ListView(
children: items.map((item) => ItemWidget(item: item)).toList(),
);
Hope that helps!
If you want to use ListView.builder then you can use as following. This may helps you.
body: ListView.builder(
itemCount: items == null ? 0 : items.length,
itemBuilder: (BuildContext context, int index) {
return ItemWidget(
item: items[index],
);
},
),