type 'string' is not a subtype of type 'int' of 'index' flutter grouped listview inside futurebuilder

202 Views Asked by At

In my flutter app, I'm trying to display the bookmarks grouped by particular field, that's why, I'm using a grouped list. The problem is when I use a static list, it shows correctly. But when I try to make the list dynamic by placing grouped listview inside a futurebuilder, and get data from shared preferences I get this error:

type 'string' is not a subtype of type 'int' of 'index'

class _BookmarkScreenState extends State<BookmarkScreen> {
  List bookmarks =[];


  @override
  void initState() {
    super.initState();
     _loadData();

    setState(() {});
  }

  Future<List<String>> _loadData() async {
    SharedPreferences pref = await SharedPreferences.getInstance();
    List<String> lb = await pref.getStringList(('bookmarks_key'));
    print(lb);
    lb.forEach((element) {
      bookmarks.add(element);
    });

    print(bookmarks);
    return bookmarks;
  }

 @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("Bookmark Screen")),
        body: Container(
            child: FutureBuilder(
    future: _loadData(),
    builder: (context, AsyncSnapshot snapshot) {
    if (!snapshot.hasData) {
    return Center(child: CircularProgressIndicator());
    } else {
                return GroupedListView<dynamic, String>(  // this is the error line
                elements: bookmarks,
                groupBy: (element) => element['surah_name'],
                groupComparator: (value1, value2) => value2.compareTo(value1),
                itemComparator: (item1, item2) =>
                    item1['verse_no'].compareTo(item2['verse_no']),
                order: GroupedListOrder.DESC,
                useStickyGroupSeparators: true,
                groupSeparatorBuilder: (String value) => Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Text(
                      value,
                      textAlign: TextAlign.center,
                      style:
                          TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                    )),
                itemBuilder: ((c, element) {
                  return Card(
                    elevation: 8.0,
                    margin: new EdgeInsets.symmetric(
                        horizontal: 10.0, vertical: 6.0),
                    child: Container(
                      child: ListTile(
                        contentPadding: EdgeInsets.symmetric(
                            horizontal: 20.0, vertical: 10.0),
                        title: Text(element['verse_no'].toString()),
                      ),
                    ),
                  );
                }));}})));
  }
}

If we remove the loadData function and futurebuilder and use a static list like this :

List bookmarks = [{"surah_no":2,"verse_no":2,"surah_name":"Al-Baqarah","favorite":true}, {"surah_no":2,"verse_no":1,"surah_name":"Al-Baqarah","favorite":true}, {"surah_no":2,"verse_no":2,"surah_name":"Al-Baqarah","favorite":true}, {"surah_no":2,"verse_no":3,"surah_name":"Al-Baqarah","favorite":true}, {"surah_no":4,"verse_no":1,"surah_name":"An-Nisa'","favorite":true}, {"surah_no":8,"verse_no":1,"surah_name":"Al-Anfal","favorite":true},];

the list is displayed in correct order. Please help what's going wrong while loading data from sheared preferences and displaying in grouped listview?

1

There are 1 best solutions below

1
Md. Yeasin Sheikh On

static list bookmarks works because it contains maps that are used by groupBy to create group.

Storing and getting List wont provide group view for most case like you are doing element['surah_name']

Now to fetch the list and just showing item you can do groupBy: (element) =>"" with return GroupedListView<String, String>(

Create a map store on database and then use on group GroupedListView