Issue
I am using multi_select_flutter to show multi chips in my flutter project. However, am trying to add more items to the chip with data loaded from my api while the user is searching but it doesn't update the state of the multi chip widget. Here is my full code.
Even when I hot reload, it does not update itself. The only way I can manually enforce a refresh update is to re-ad the widget and reload consecutively. Any information as to why this strange behavior happens?
class MultiChoiceComponent extends StatefulWidget {
const MultiChoiceComponent({Key key}) : super(key: key);
@override
_MultiChoiceComponentState createState() => _MultiChoiceComponentState();
}
class _MultiChoiceComponentState extends State<MultiChoiceComponent> {
ApiMethods apiMethods;
TextEditingController searchController = TextEditingController();
List<MultiSelectItem<dynamic>> labels = [];
final TextEditingController textEditingController = TextEditingController();
@override
void initState() {
// TODO: implement initState
super.initState();
apiMethods = new ApiMethods(context: context);
}
@override
Widget build(BuildContext context) {
return ListView(
shrinkWrap: true,
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Text(
'Search and select as many symptoms been experienced, it helps with a more accurate diagnosis',
textAlign: TextAlign.start,
style: TextStyle(
fontSize: 14,
height: 1.8,
fontWeight: FontWeight.w400,
fontFamily: 'Euclid',
color: AppColors.grey1,
),
),
),
SizedBox(
height: 20,
),
Container(
padding: EdgeInsets.symmetric(horizontal: 16,),
// height: maxLines * 50.0,
child: TextField(
controller: textEditingController,
cursorColor: Colors.black26,
onChanged: (val){
if(val!=""){
searchSymptoms(val);
}
},
decoration: InputDecoration(
filled: true,
hintStyle: TextStyle(
fontSize: 14,
height: 1.6,
fontWeight: FontWeight.w400,
fontFamily: 'Euclid',
color: AppColors.grey1,
),
hintText: "Search for a symptom/illness",
fillColor: Colors.white,
contentPadding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 14),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: AppColors.textColor.withOpacity(0.5)),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: AppColors.textColor.withOpacity(0.5)),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12.0),
borderSide: BorderSide(color: AppColors.textColor.withOpacity(0.5)),
)),
),
),
MultiSelectChipField(
scroll: false,
decoration: BoxDecoration(
border: Border.all(color: Colors.transparent, width: 1.8),
),
showHeader: false,
selectedTextStyle: TextStyle(
fontSize: 12.5,
height: 1.8,
fontWeight: FontWeight.w400,
fontFamily: 'Euclid',
color: Colors.white,
),
chipShape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
selectedChipColor: AppColors.customGreen,
chipColor: Colors.white,
textStyle: TextStyle(
fontSize: 12.5,
height: 1.8,
fontWeight: FontWeight.w400,
fontFamily: 'Euclid',
color: AppColors.textColor,
),
items: labels,
onTap: (value) {
///add symptoms to list
print(value);
selectedSymptoms = value as List<Conditions>;
},
),
],
);
}
Future<void> searchSymptoms(String searchQuery) async {
List<dynamic> _data = await apiMethods.searchConditions(symptomCheckerAge, searchQuery);
conditions = Conditions.fromJsonList(_data);
labels = conditions.map((e) => MultiSelectItem(e, e.label)).toList();
setState(() {});
}
}
Solution
Can you share the full code.. like the part where you have declared variables like labels and conditions. You need to make sure that these variables are not final firstly and that these are using the late keyword or something like List? labels. If there's any other problem kindly share the whole code of this stateful class
**EDIT
So I tried this given Chip Widget with custom data and it is working properly.. Meaning the items that i am adding on pressed are being added to the new list. Take a look and try out the few changes and see if that works for you
class _MyHomePageState extends State<MyHomePage> {
static List<Animal> _animals = [
Animal(id: 1, name: "Lion"),
Animal(id: 2, name: "Flamingo"),
Animal(id: 3, name: "Hippo"),
Animal(id: 4, name: "Horse"),
Animal(id: 5, name: "Tiger"),
Animal(id: 6, name: "Penguin"),
Animal(id: 7, name: "Spider"),
Animal(id: 8, name: "Snake"),
Animal(id: 9, name: "Bear"),
Animal(id: 10, name: "Beaver"),
Animal(id: 11, name: "Cat"),
Animal(id: 12, name: "Fish"),
Animal(id: 13, name: "Rabbit"),
];
dynamic _items = _animals
.map((animal) => MultiSelectItem<Animal>(animal, animal.name))
.toList();
@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.white,
appBar: new AppBar(
title: new Text('Hello'),
),
body: ListView(
scrollDirection: Axis.vertical,
physics: NeverScrollableScrollPhysics(),
children: [
Container(
child: MultiSelectChipField(
scroll: false,
decoration: BoxDecoration(
border: Border.all(color: Colors.transparent, width: 1.8),
),
showHeader: false,
selectedTextStyle: TextStyle(
fontSize: 12.5,
height: 1.8,
fontWeight: FontWeight.w400,
color: Colors.blue,
),
chipShape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
selectedChipColor: Colors.green,
chipColor: Colors.yellow,
textStyle: TextStyle(
fontSize: 12.5,
height: 1.8,
fontWeight: FontWeight.w400,
color: Colors.black,
),
items: _items,
onTap: (value) {
///add symptoms to list
print(value);
},
),
),
ElevatedButton(
onPressed: () {
_items.add(MultiSelectItem<Animal>(
Animal(id: 27, name: 'name'), 'new'));
setState(() {});
},
child: Text('Add'))
],
),
);
}
}
class Animal {
final int id;
final String name;
Animal({
required this.id,
required this.name,
});
}
Answered By - Yash Bhansali
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.