I have a question about GridListView with firestore.
I want to use GridList with firestore but some errors are happen.
lib/main.dart:75:15: Error: No named parameter with the name 'children'. children: workoutList ^^^^^^^^ ../../Developer/flutter/packages/flutter/lib/src/widgets/scroll_view.dart:1729:3: Context: Found this candidate, but the arguments don't match. GridView.builder({
Could you give me some ideas?
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
children: workoutList
.map(
(workout) => CheckboxListTile(
title: Text(
workout.title,
style: TextStyle(
color: Colors.white
),
),
value: workout.isDone,
onChanged: (bool value) {
workout.isDone = !workout.isDone;
model.reload();
},
),
)
.toList()
);
The error message is quite explanatory. All it's telling you is that the GridView.builder() constructor has no parameter 'children'. The code below is way to achieve what you're trying to do:
return GridView.builder(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemCount: workoutList.length,
itemBuilder: (BuildContext context, int index) {
var workout = workoutList[index];
return CheckboxListTile(
title: Text(
workout.title,
style: TextStyle(color: Colors.white),
),
value: workout.isDone,
onChanged: (bool value) {
workout.isDone = !workout.isDone;
model.reload();
},
);
},
);
Related
My code is as follows:
final TextEditingController _locationController = TextEditingController();
late TextEditingController myController;
late List<String> locationSuggestions; // Populated with options in code first
Autocomplete<String>(
initialValue: TextEditingValue(text:_locationController.text),
optionsMaxHeight: 50,
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text.isEmpty) return const Iterable<String>.empty();
return locationSuggestions.where((String option) {
return option
.toLowerCase()
.contains(textEditingValue.text.toLowerCase());
});
},
optionsViewBuilder: (context, onSelected, options){
return Material(
elevation: 8,
child: ListView.separated(
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 0.0),
itemBuilder: (BuildContext context, int index) {
final String option = options.elementAt(index);
return ListTile(
dense: true,
// tileColor: Colors.deepOrange,
title: SubstringHighlight(
text: option,
term: myController.text,
textStyleHighlight: const TextStyle(fontWeight: FontWeight.w700, fontSize: 16.0),
),
onTap: () => onSelected(option),
);
},
separatorBuilder: (context, index) => const Divider(),
itemCount: options.length,
));
},
onSelected: (String value)=> myController.text = value,
fieldViewBuilder: (context, controller, focusNode, onEditingComplete){
myController = controller;
return TextFormField(
controller: myController,
focusNode: focusNode,
maxLines: 1,
maxLength: 30,
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.sentences,
decoration: InputDecoration(
labelText: 'Location',
prefixIcon: Icon(
Icons.add_location,
size: 35.0,
color: Theme.of(context).colorScheme.primary,
)),
onEditingComplete: onEditingComplete,
//onTap: ()=>FocusManager.instance.primaryFocus?.unfocus(),
);
},
),
The Problem:
When I go and type the text, I see options appearing below, if I choose one of the options, all goes well and good.
BUT... I am not able to type a new 'similar' custom option. So for example, if I get a suggestion for the word 'Apple' and I just want to stop typing at App, I can't do it. The done button on the keyboard does not hide the keyboard and if I try to move away from the field the entire 'Apple' appears in the text field. I tried experimenting with unfocus but it is not the right way and I am sure I am missing a feature here.
I have a list of varieties [Chocolate, Strawberry, Vanilla]
This list can change depending on the menu item ordered (i.e. [BBQ, Medium, Peri-Peri, Lemon & Herb])
My current code which display the button correctly but is not functional is:
ListView.builder(
shrinkWrap: true,
itemCount: varietyList.length,
itemBuilder: ((context, index) {
return GFRadioListTile(
titleText: varietyList[index],
size: 25,
activeBorderColor: Colors.black,
focusColor: Colors.black,
type: GFRadioType.basic,
value: 0,
groupValue: 1,
onChanged: (value) {},
inactiveIcon: null,
);
})),
Where ```int number = 20'''. This variable and amount was based off another post where the code looked as follow:
ListView.builder(
shrinkWrap: true,
itemCount: varietyList.length,
itemBuilder: ((context, index) {
return RadioListTile(
value: index,
groupValue: number,
onChanged: (ind) => setState(() => number = ind),
);
})),
But it says "A value of type 'Object?' can't be assigned to a variable of type 'int'."
How can I get the radio button functional?
to fix the "object cant be int" problem I had to add as int for the ind object.
GFRadioListTile(
padding: const EdgeInsets.all(13),
color: Colors.white,
radioColor: Color.fromARGB(255, 138, 5, 5),
title: Text(
varietyList[index],
style: const TextStyle(
fontSize: 25, color: Colors.black),
),
size: 28,
activeBorderColor: Colors.black,
focusColor: Colors.black,
type: GFRadioType.basic,
value: index,
groupValue: number,
onChanged: (ind) =>
setState(() => number = ind! as int),
inactiveIcon: null,
);
hey I want to make an int variable, but it got an error. please help. the error is the line
onChanged: (i) => setState(() => value = i),
actually the last i only, get the red underline, said : A value of type 'Object?' can't be assigned to a variable of type 'int'.
and this is the code :
class Payment extends StatefulWidget {
#override
_PaymentState createState() => _PaymentState();
}
class _PaymentState extends State<Payment> {
int value = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("SPARK Payment Page"),
centerTitle: true,
),
body: Column(
children: [
HeaderLabel(
headerText: 'Choose your payment method',
),
Expanded(
child: ListView.separated(
itemCount: paymentLabels.length,
itemBuilder: (context, index) {
return ListTile(
leading: Radio(
activeColor: Colors.black,
value: index,
groupValue: value,
onChanged: (i) => setState(() => value = i),
),
title: Text(
paymentLabels[index],
style: TextStyle(color: Colors.blue),
),
trailing: Icon(paymentIcons[index], color: Colors.blue),
);
},
separatorBuilder: (context, index) {
return Divider();
},
),
),
DefaultButton(
btnText: 'Pay',
onPressed: () => Navigator.of(context).push(MaterialPageRoute(
builder: (context) => Success(),
)))
],
),
);
}
}
I've changed the int value = i to String? value ="0";
and I've changed onChanged: (i) => setState(() => value = i as String?)
that make the red underline gone, but when I ran the app, it returns an error like this :
_CastError (type 'int' is not a subtype of type 'String?' in type cast)
set your onChanged to:
onChanged: (i) => setState(() => value = i as int?),
or, set the type of the Radio by typing Radio<int?>:
ListTile(
leading: Radio<int?>(
activeColor: Colors.black,
value: index,
groupValue: value,
onChanged: (i) => setState(() => value = i),
),
title: Text(
paymentLabels[index],
style: TextStyle(color: Colors.blue),
),
trailing: Icon(paymentIcons[index], color: Colors.blue),
),
The problem is you the object you have defined is not an int, and you wanted to define it as an int with the value of i, i is an int
you should change the value to int or convert it into an int.
or do this instead set the Radio<int?> if that doesn't work, Radio?
I was wondering if it was possible to make items in List View unique in the sense that if I want to add something to the one, it only changes that particular list tile item, for example, if I added a leading icon from the DropDown to the one on the list, it adds that icon only to that particular list tile, and not the others (I can then add other icons from the dropdown to other list tile items).
Here's the code for it, I am not sure if this is possible since the builder is made from Bloc and an existing class Person, basically a template for each list item. I have tried with adding UniqueKey(), but that seems not to do anything. Here's the code for the List View:
_chosenSize
String _chosenSize;
child: BlocConsumer<PersonBloc, List<Person>>(
builder: (context, personList) {
return ListView.separated(
itemBuilder: (BuildContext context, int index) {
print("personList: $personList");
Person person = personList[index];
return ListTile(
key: UniqueKey() //added unique key here, but it still fails
//for example, is it possible to make this list tile unique
//if I make change to it, it only changes the one I change, and not
//all of them in a list at once
leading: _buildSize(); //DROPDOWN HERE
trailing: Icon(Icons.person),
title: Text("${person.name} ${person.age}",
style: TextStyle(fontSize: 30)),
subtitle: Text(
"person.name",
style: TextStyle(fontSize: 25),
),
onTap: () => showDialog(context, person, index));
},
itemCount: personList.length,
separatorBuilder: (BuildContext context, int index) =>
Divider(color: Colors.black),
);
},
listener: (BuildContext context, personList) {},
),
Then here's the code for the DropDown:
Widget _buildSize() {
return DropdownButton<String>(
focusColor: Colors.white,
value: _chosenSize,
//elevation: 5,
style: TextStyle(color: Colors.white),
iconEnabledColor: Colors.black,
items: <String>[
'',
'S',
'M',
'L',
'XL',
].map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: TextStyle(color: Colors.black),
),
);
}).toList(),
hint: Text(
"Size",
style: TextStyle(
color: Colors.black, fontSize: 14, fontWeight: FontWeight.w500),
),
onChanged: (String value) {
setState(() {
_chosenSize = value;
});
},
)};
What happens is that when I change the 'size' option from the dropdown, it changes for all list tiles, I need it to change only for one and then save the state of it. Here's what happens:
You need to create a list for _chosenSize as well, which you pass to Widget _buildSize(String _chosenSize) with _buildSize(_chosenSize[index]) and also store it there with onChanged
class MyPageState extends State<MyPage> {
List<String> _chosenSizes = [];
...
return ListView.separated(
itemBuilder: (BuildContext context, int index) {
print("personList: $personList");
Person person = personList[index];
return ListTile(
key: UniqueKey() //added unique key here, but it still fails
//for example, is it possible to make this list tile unique
//if I make change to it, it only changes the one I change, and not
//all of them in a list at once
leading: _buildSize(index]); //DROPDOWN HERE
trailing: Icon(Icons.person),
title: Text("${person.name} ${person.age}",
style: TextStyle(fontSize: 30)),
subtitle: Text(
"person.name",
style: TextStyle(fontSize: 25),
),
onTap: () => showDialog(context, person, index));
},
itemCount: personList.length,
separatorBuilder: (BuildContext context, int index) =>
Divider(color: Colors.black),
);
...
Widget _buildSize(int index) {
return DropdownButton<String>(
focusColor: Colors.white,
value: _chosenSizes[index],
...
onChanged: (String value) {
setState(() {
_chosenSizes[index] = value;
});
},
)};
}
I'm creating an application which requires the user to select a value from the drop-down from every item of grid view. But when I select a value from a drop-down it changes value for other drop-down too.
GridView.builder(
itemCount: 50,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, childAspectRatio: 1),
itemBuilder: (BuildContext context, int index) {
return new Card(
child: Column(
children: [
DropdownButton(
hint: _dropDownValue == null
? Text('Dropdown')
: Text(
_dropDownValue,
style: TextStyle(color: Colors.blue),
),
isExpanded: true,
iconSize: 30.0,
style: TextStyle(color: Colors.blue),
items: ['One', 'Two', 'Three'].map(
(val) {
return DropdownMenuItem<String>(
value: val,
child: Text(val),
);
},
).toList(),
onChanged: (val) {
setState(
() {
_dropDownValue = val;
},
);
},
)
],
),
);
},
),
This is the code I'm using.
Screenshot of Problem I'm Facing
This happens because you retrieve the value for every DropDown using _dropDownValue. In order to make it work, you have to store each selection for each Grid using a e.g. List or Map.
class MyWidget extends StatefulWidget {
const MyWidget({Key key}) : super(key: key);
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
List<String> values = [
"Grid 1 selection",
"Grid 2 selection",
"..."
];
#override
Widget build(BuildContext context) {
return GridView.builder(
itemCount: 50,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, childAspectRatio: 1),
itemBuilder: (BuildContext context, int index) {
return new Card(
child: Column(
children: [
DropdownButton(
hint: values[index] == null
? Text('Dropdown')
: Text(
values[index],
style: TextStyle(color: Colors.blue),
),
isExpanded: true,
iconSize: 30.0,
style: TextStyle(color: Colors.blue),
items: ['One', 'Two', 'Three'].map(
(val) {
return DropdownMenuItem<String>(
value: val,
child: Text(val),
);
},
).toList(),
onChanged: (val) {
setState(
() {
values[index] = val;
},
);
},
)
],
),
);
},
);
}
}