so I am using MultiSelectBottomSheetField in this package. I posted on their github as well as an issue but it seems fairly inactive so i came here looking for help.
And I am having some issues with the initialValue parameter for it. So at the moment, I have data saved in firestore as a string but its in the format of a list. And what i was trying to do was get the string data from firestore -> convert to a list with the respective class -> and then show as initial value in the above package/widget. But whats happening is that the initial value isnt showing, even though the value is not empty.
So for context this is how I change to list from firestore string:
List<Skill?> skillList = [];
void changeSkillToList(String? stringList) {
int indexOfOpenBracket = stringList!.indexOf("[");
int indexOfLastBracket = stringList.lastIndexOf("]");
var noBracketString =
stringList.substring(indexOfOpenBracket + 1, indexOfLastBracket);
var list = noBracketString.split(", ");
for (var i = 0; i < list.length; i++) {
skillList.add(Skill(id: 1, name: list[i].toString()));
}
}
this is how i use the acc widget:
final _skillItems =
skill.map((skill) => MultiSelectItem<Skill>(skill, skill.name)).toList();
MultiSelectBottomSheetField<Skill?>(
selectedColor: Color(0xFF5DB075),
selectedItemsTextStyle:
TextStyle(color: Colors.white),
initialChildSize: 0.4,
decoration: BoxDecoration(),
listType: MultiSelectListType.CHIP,
initialValue: skillList,
searchable: true,
items: _skillItems,
buttonText: Text("Select your skills...",
style: GoogleFonts.inter(
color: Color(0xFFBDBDBD),
fontSize: 16)),
onConfirm: (values) {
context
.read(pharmacistSignUpProvider.notifier)
.changeSkillList(values);
},
chipDisplay: MultiSelectChipDisplay(
items: context
.read(pharmacistSignUpProvider.notifier)
.skillList
?.map((e) =>
MultiSelectItem(e, e.toString()))
.toList(),
chipColor: Color(0xFF5DB075),
onTap: (value) {
context
.read(
pharmacistSignUpProvider.notifier)
.skillList
?.remove(value);
return context
.read(
pharmacistSignUpProvider.notifier)
.skillList;
},
textStyle: TextStyle(color: Colors.white),
),
),
And this is my initState:
List<Skill?> skillList = [];
#override
void initState() {
skillList = changeSkillToList(context
.read(pharmacistMainProvider.notifier)
.userDataMap?["knownSkills"]);
print(skillList);
super.initState();
}
If someone could help me out, it would be very appreciated. Let me know if you guys have any questions
Thanks!!
I get some problem and I fix it by adding the == operator to my entity in your case skill
#override
bool operator ==(Object other) {
return other is Skill && this.id == other.id;
}
inside your Skill class
Related
This is my search code. It works by typing id the codes to display the information.
onSearch(String text) async {
if (text.isNotEmpty) {
List<Item> itemList = [];
for (var item in items) {
if (item.custnum == text.toLowerCase().toUpperCase()) {
itemList.add(item);
}
}
setState(() {
searchitems.clear();
searchitems.addAll(itemList);
print('name : ${searchitems[0].name}');
// if (searchitems.isEmpty) {
// searchitems = [];
// print('searchitems : ${searchitems[0].address!.length}');
// print('searchitems : ${searchitems[0].address!}');
});
} else {
setState(() {
searchCus.clear();
searchitems.clear();
// searchitems.addAll(items);
print('searchitems : $searchitems');
});
}
}
This is my textformfield, it can find and display data. But what I will do is Getting a code from another page It's received and shows the code. But it doesn't show me the information. It has to delete and type at least 1 new password to show the information. Please help me i tried a lot.
TextFormField(
initialValue:
'${searchCus.isEmpty ? "" : searchCus[widget.indexCus].custnum}',
onChanged: onSearch,
decoration: InputDecoration(
labelText: 'custnum',
labelStyle: TextStyle(fontFamily: 'supermarket', fontSize: 14),
isDense: true,
),
),
The reason the initial value not do the search is that you search logic is only works when you type in the textfield, if your initial value come from class constructor you can call onSearch in initState like this:
#override
void initState() {
super.initState();
if(searchCus.isNotEmpty){
onSearch(searchCus[widget.indexCus].custnum);
}
}
I am currently creating a dropdown where the value of it should by dynamic depending the selected value that I am going to use in different widget. This is my current dropdown stateful widget:
periodic_modal.dart
extension StringExtension on String {
String capitalize() {
return "${this[0].toUpperCase()}${this.substring(1).toLowerCase()}";
}
}
class DropDown1 extends StatefulWidget {
DropDown1({super.key});
#override
State<DropDown1> createState() => _DropDown1State();
}
class _DropDown1State extends State<DropDown1> {
String? selectedMonth;
String? selectedYear;
#override
Widget build(BuildContext context) {
print("Selection month = ${Selection.currMonth}");
return Row(
children: [
DropdownButton(
// isExpanded: true,
hint: Text("Pilih Bulan"),
underline: Container(
height: 2,
color: Colors.black,
),
icon: Visibility(visible: false, child: Icon(Icons.arrow_downward)),
items: months
.map((item) => DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(
fontSize: 14,
color: Colors.black,
),
overflow: TextOverflow.ellipsis,
),
))
.toList(),
value: Selection.currMonth.capitalize().isEmpty?null:Selection.currMonth.capitalize(),
onChanged: (value) {
setState(() {
selectedMonth = value as String;
Selection.currMonth = value as String;
Selection.nextMonth = value as String;
});
},
),
SizedBox(
width: 50,
),
DropdownButton(
underline: Container(
height: 2,
color: Colors.black,
),
icon: Visibility(visible: false, child: Icon(Icons.arrow_downward)),
items: years
.map((item) => DropdownMenuItem<String>(
value: item,
child: Text(
item,
style: const TextStyle(
fontSize: 14,
color: Colors.black,
),
overflow: TextOverflow.ellipsis,
),
))
.toList(),
hint: Text("Pilih Tahun"),
value: Selection.currYear == -1 ? null : Selection.currYear.toString(),
onChanged: (value) {
setState(() {
// selectedYear = value as String;
Selection.currYear = value as int;
print("value = ${value} selection currYear = ${Selection.currYear}");
print("Selection.currYear = ${Selection.currYear}");
Selection.nextYear = value as int;
print("Selection.nextYear = ${Selection.nextYear}");
});
})
],
);
}
}
home_page.dart (Part of this whole file)
class Selection{
static int _currYear = 0;
static String _currMonth = "";
static int _nextYear = 0;
static String _nextMonth = "";
static int get currYear => _currYear;
static String get currMonth => _currMonth;
static int get nextYear => _nextYear;
static String get nextMonth => _nextMonth;
static set currYear(int value) => _currYear = value;
static set currMonth(String value) => _currMonth = value;
static set nextYear(int value) => _nextYear = value;
static set nextMonth(String value) => _nextMonth = value;
}
after I did a small debugging, I have an inkling that there is something wrong on this part of code within periodic_model.dart
onChanged: (value) {
setState(() {
// selectedYear = value as String;
Selection.currYear = value as int;
print("value = ${value} selection currYear = ${Selection.currYear}");
print("Selection.currYear = ${Selection.currYear}");
Selection.nextYear = value as int;
print("Selection.nextYear = ${Selection.nextYear}");
});
})
if I write print("value = ${value} selection currYear = ${Selection.currYear}"); above Selection.currYear = value as int; it prints successfully before I get the error. But if I did it the way I do it in the snippet - I got the error without print the print, therefore I assume there is something wrong in Selection.currYear = value as int; although I am not 100% sure.
How should I fix this?
//Edit
this is the list for years
final List<String> years = [
'2022',
'2021',
'2020',
'2019',
'2018',
'2017',
'2016',
'2015',
'2014',
'2013',
'2012',
'2011',
'2010',
'2009',
];
//Edit 2:
This is the class for Selection that is placed in home_page.dart
class Selection{
static List<List<Map<String,String>>> dataDummy = dummy;
static int _currYear = 0;
static String _currMonth = "";
static int _nextYear = 0;
static String _nextMonth = "";
static int get currYear => _currYear;
static String get currMonth => _currMonth;
static int get nextYear => _nextYear;
static String get nextMonth => _nextMonth;
static set currYear(int value) => _currYear = value;
static set currMonth(String value) => _currMonth = value;
static set nextYear(int value) => _nextYear = value;
static set nextMonth(String value) => _nextMonth = value;
}
I guess years data is List<String>.
int.parse(value);
Insert upper line before Selection.currYear = value as int;
Hope to working well. Happy Coding 🧑💻
I managed to find the answer, however I am not entirely sure if my approach is the right one or not but for this particular problem, it manages to fix it.
Within setState() on the line of
Selection.currYear = value as int;
I change it to
Selection.currYear = int.parse(value??"0");
and I also did it for
Selection.nextYear = value as int;
too
int _genelScore = 0;
#override
void initState() {
super.initState();
_setScore();
}
void _setScore() async {
await SharedPreferences.getInstance().then((sharedPreferences) {
setState(() {
_genelScore = sharedPreferences.getInt("genelScore")!;
});
});
}
I'm designing a simple app where the user is trying to answer a question and score. But " Null check operator used on a null value." I can't get rid of the error. The code above is the page where I show the number of questions that the user knows.
I tried to write int? _generalScore = 0 and make _generalScore nullable. This time, the application works, but if the user misunderstands the first question, high score : null is written on my screen.
Text(
"HIGH SCORE",
textAlign: TextAlign.center,
style: GoogleFonts.montserrat(
color: Color.fromARGB(255, 0, 0, 0),
),
),
const SizedBox(
height: 12,
),
Text("$_genelScore",
textAlign: TextAlign.center,
style: GoogleFonts.montserrat(
color: Colors.black)),
Here is my code where I print the user's record to the screen.
void _updateBestScoreIfNecessary(int correctAnswers) async {
await SharedPreferences.getInstance().then((sharedPreferences) {
var bestScore = sharedPreferences.getInt("genelScore");
bestScore ??= 0;
if (bestScore < correctAnswers) {
sharedPreferences.setInt("genelScore", correctAnswers);
}
});
}
Finally, here is my code where I make a key-value match with the word "genelScore" with sharedPreferences.
Initially, At the first time open The genelScore key from SharedPreferences does not any values saved. So, sharedPreferences.getInt("genelScore")!; returns null.
Do,
_genelScore = sharedPreferences.getInt("genelScore") ?? 0;
I am using flutter_tags package in my project. when i add text in the TagsTextField and press Enter I get below error and that part becomes red.
Expected a value of type 'DataList', but got one of type 'Null'
Code:
List subs = [];
final GlobalKey<TagsState> _globalKey = GlobalKey<TagsState>();
// Rest of the code
Tags(
key: _globalKey,
itemCount: subs.length,
columns: 6,
textField: TagsTextField(
textStyle: const TextStyle(fontSize: 14),
onSubmitted: (String str) {
setState(() {
subs.add(
Item(title: str),
);
showDialogBox(context, "showing", subs.toString());
});
}),
itemBuilder: (i) {
final currentItem = subs[i]!;
print(currentItem);
return ItemTags(
index: i,
title: currentItem.title,
customData: currentItem.customData,
onPressed: (curr) => print(curr),
onLongPressed: (curr) => print(curr),
removeButton: ItemTagsRemoveButton(
onRemoved: () {
setState(() {
subs.removeAt(i);
});
return true;
},
),
);
},
)
// rest of the code
*Before Clicking Enter
After I Click Enter
remove this line
customData: currentItem.customData,
and it will work.
Edit: Updated my comment.
title: currentItem.title <- the types do not match, one is String and the other is String? You need to read the documentation on how to handle/use null safety in dart.
https://dart.dev/null-safety/understanding-null-safety
Could also be due to your list not being initialized properly. Try the below:
List subs= List.empty(growable: true);
There are two FilterChips and clicking the selected one will open the progress indicator again. So every time I click on the FilterChip already selected it calls the controller again and the progress indicator returns.
I want nothing to happen when the selected one is clicked but I don't understand the logic.
Also api1Type must be come always true. And loadingController calling progress indicator.
Filter Controller
var filterTypeNumb = 0;
var filterList = [].obs;
RxBool api1Type = true.obs;
RxBool api2Type = false.obs;
void getFilterType() {
if (filterTypeNumb == 0) {
filterList(api1Controller.api1List);
api1Type(true);
api2Type(false);
loadingController2Sec.getLoading();
} else if (filterTypeNumb == 1) {
filterList(api2Controller.api2List);
api1Type(false);
api2Type(true);
loadingController2Sec.getLoading();
}
}
#override
void onInit() {
getFilterType();
super.onInit();
}
}
Filter Chip
FilterTypeController filterTypeController = Get.put(FilterTypeController());
FilterChip(
label: Text(
"Filter 1",
style: fAppNavBarTextStyle,
),
checkmarkColor: Colors.white,
selectedColor: cButtonColor,
backgroundColor: const Color(0xFF878787),
selected:
filterTypeController.api1Type.value,
onSelected: (bool value) {
filterTypeController.filterTypeNumb = 0;
value =
filterTypeController.api1Type.value;
filterTypeController.getFilterType();
//Get.back();
}),
FilterChip(
label: Text(
"Filter 2",
style: fAppNavBarTextStyle,
),
selectedColor: cGetFreeColor,
backgroundColor: const Color(0xFF878787),
selected:
filterTypeController.api2Type.value,
onSelected: (bool value) {
filterTypeController.filterTypeNumb = 1;
value =
filterTypeController.api2Type.value,
filterTypeController.getFilterType();
//Get.back();
}),