I tried to make a Text, which should only be visible, if variable1 == "1", but I got an error. can anybody tell me why I get this error? Below is the code I tried. Thanks in advance!
Padding(
padding: const EdgeInsets.symmetric(vertical: 28.0),
child:
Container(
child: variable1 == "1"
?Text(
"Test",
style: TextStyle(fontSize: 25),
),
),
),
You are getting the error because you didn't add the else part of the ternary operator.
Check the code below: It adds an empty Container that is not visible if variable1 != null.
Padding(
padding: const EdgeInsets.symmetric(vertical: 28.0),
child: Container(
child: variable1 == "1"
? Text(
"Test",
style: TextStyle(fontSize: 25),
)
: Container(),
),
);
I hope this helps.
You need to add something to be returned if the condition is false with :
Ternary operation syntax:
[condition] ? [do this if the condition is true] : [do this if the condition is false]
In your case, you should return a SizedBox as it is more efficient.
Like this
Container(
child: variable1 == "1"
? Text(
"Test",
style: TextStyle(fontSize: 25)
)
: SizedBox()
)
you have to add, what if condition is wrong. You can specify after doing(:). as i specified empty text.
child: variable1 == "1"
?Text(
"Test",
style: TextStyle(fontSize: 25),
): Text(""),
Related
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.
I have a json list. from this i want to delete a particular item. Below is my code.
final List _vehicleList = [
{
'vehicleNumber': 'KL-14-V-5208',
'vehicleType': 'Two Wheeler',
},
{
'vehicleNumber': 'KL-13-H-8880',
'vehicleType': 'Four Wheeler',
},
{
'vehicleNumber': 'KL-14-M-6889',
'vehicleType': 'Three Wheeler',
},
];
This is my list. Here from this i want to delete the item based on vehicleNumber when i press a delete button. I'am using listview builder. When i print the list after the button press nothing happens
This is my UI Code.
return Column(
children: [
Padding(
padding: const EdgeInsets.all(12.0),
child: Text(
_vehicleList[index]['vehicleNumber'],
),
),
Padding(
padding: const EdgeInsets.all(12.0),
child: Text(
_vehicleList[index]['vehicleType'],
),
),
GestureDetector(
onTap: () {
print('Deleted');
_vehicleList.removeAt(_vehicleList[index]);
print(_vehicleList);
},
child: const Padding(
padding: EdgeInsets.all(12.0),
child: Icon(
FontAwesomeIcons.timesCircle,
color: Colors.redAccent,
),
),
),
],
);
You should change like this;
Before;
_vehicleList.removeAt(_vehicleList[index]);
after
_vehicleList.removeAt(index);
Documentation of how to use the "removeAt" method. https://api.flutter.dev/flutter/dart-core/List/removeAt.html
Try below code hope its help to you. just pass your index
_vehicleList.removeWhere((element) => element["vehicleNumber"] == 'KL-14-V-5208');
Some of my classes uses assert() to make development easier.
The problem is that those asserts are ignored in production mode, so I need a way to write tests for times when those assertions fail (when they throw assertionErrors).
main() {
// test if the assertion is being throw correctly
test('null emailStr assertion', () {
expect(() => Email(emailStr: null), throwsAssertionError);
});
// here I want to test how it would behave in prod mode
// when the asserts are ignored.
// This way it'll just throw an assertion error
test('null emailStr emailStr value', () {
final Email email = Email(emailStr: null);
expect(email.isValid, false);
});
}
I wonder if there's something like this to run tests as if we were in production mode:
setUp(isCheckedMode = false)
I found in google that the only way to message someone in stack is to write a comment in his question.
However, my code of another class (MessageBubble) is:
class MessageBubble extends StatelessWidget {
final String messsage;
final userID;
final bool isMe;
final Key key;
MessageBubble(this.messsage,this.userID, this.isMe,this.key);
#override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: isMe? MainAxisAlignment.start: MainAxisAlignment.end,
children: [
Container(
decoration: BoxDecoration(
color: isMe? Colors.grey[300]: nave,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
bottomLeft: !isMe ? Radius.circular(12) : Radius.circular(0),
bottomRight: isMe ? Radius.circular(12) : Radius.circular(0),
),
),
width: 140,
padding: EdgeInsets.symmetric(vertical: 10,horizontal: 16),
margin: EdgeInsets.symmetric(vertical: 4, horizontal: 8),
child: Column(
children: [
Column(
children: [
FutureBuilder(
future: FirebaseFirestore.instance.collection('users').doc(userID).get(),
builder: (context, snapshot) {
if(snapshot.connectionState== ConnectionState.waiting){
return Text('جاري التحميل...');}
return Text(snapshot.data['username'], style: TextStyle(fontWeight: FontWeight.bold),);
}
),
],
),
Text(messsage, style: TextStyle(color: isMe? white : Colors.black,),),
],
) ,
),
],
);
}
}
my code in main:
home:
StreamBuilder(stream: FirebaseAuth.instance.authStateChanges(), builder: (ctx, userSnapshot) {
if (userSnapshot.hasData) {
return ChatPage();
}
return FirstPage();
}),
I am currently having a few difficulties with ReorderableListView.
I have a list of ToDoPrefabs, which I want to output, because my list does not consist of strings but something else, I get errors in the index, for the key and the text.
this is the error:
"type 'To Prefab' is not a subtype of type 'int'"
I suspect that this is the key. It is also logical since todoprefab is not an int. Does anyone have an idea how I can get another index of the type int in my ReorderableListView
This is my ReorderableListView
return ReorderableListView(
onReorder: _onReorder,
scrollDirection: Axis.vertical,
padding: const EdgeInsets.symmetric(vertical: 8.0),
children: [
for(final item in toDoManagerClass.todoBank)
todocardprefab(item)
]
);
the todocardprefab (not the list)
todocardprefab(var key){
return Dismissible(
key: ValueKey(key),
background: Container(color: Colors.red, alignment: Alignment.centerLeft, child: Icon(Icons.delete),),
secondaryBackground: Container(color: Colors.green, alignment: Alignment.centerRight, child: Icon(Icons.archive),),
child: Card(
child: ListTile(
//leading: Icon(Icons.check_box_outline_blank),
title: Text(toDoManagerClass.todoBank[key].toDoText),
onTap: (){},
),
),
);
}
and this is the simple list.
class ToDoManagerClass{
List<ToDoPrefab> todoBank = [
ToDoPrefab(text: 'Homework', f: false),
ToDoPrefab(text: 'Homework1', f: false),
ToDoPrefab(text: 'Homework12', f: false),
ToDoPrefab(text: 'Homework123', f: false),
ToDoPrefab(text: 'Homework1234', f: false),
ToDoPrefab(text: 'Homework12345', f: false),
];
}
This method should work:
Your reordable listview
return ReorderableListView(
onReorder: _onReorder,
scrollDirection: Axis.vertical,
padding: const EdgeInsets.symmetric(vertical: 8.0),
children: [
for(final item in toDoManagerClass.todoBank)
todocardprefab(item, index())
]
);
and here the function. It returns a number higher with each call.
int index(){
if(i < toDoManagerClass.todoBank.length){
print(i);
i++;
}
return i-1;
}
now you only have to use the index instead of the item in your todocard
My function types() should return a unique list of ExpansionTiles.
In dart combining .toSet().toList() is really efficient in removing duplicates in List and I am trying to do the same here but I'm still rendering duplicates.
In the picture I don't want NISSAN to appear twice, just once as one category.
types() {
return snapshot.data.documents.map((doc) {
if(doc['car']['registryNumber'] != null && doc['car']['category'] ==
'car') {
return ExpansionTile(
title: new Row(
children: <Widget>[
new Text(
doc['car']['type'].split(' ')[0],
style: new TextStyle(
fontSize: 15.0
),
)
],
),
children: <Widget>[
],
);
} else {
return new Text('');
}
}).toSet().toList();
}
Don't forget to add a unique key: to ExpansionTile to avoid any duplicate issues!