Dart Showing only specific Items of a list based on a characteristic of the items

Viewed 389

I have a basic Items list which contains an itemType the class goes like this:

class ItemType {
  static const a= 'Aitems';
  static const b= 'Bitems';
  static const c= 'Citems';
}

class ItemList {
  String id;
  String itemType;
  String title;
  String icon;
  List<String> tags;

  ItemList({
    required this.id,
    required this.itemType,
    required this.title,
    required this.icon,
    this.tags = const [],
  });

  factory ItemList.fromJson(Map<String, dynamic> json) {
    return ItemList(
      id: json['id'] ?? '',
      soundType: json['itemType'] ?? '',
      title: json['title'] ?? '',
      icon: json['icon'] ?? '',
      tags: json['tags'].cast<String>() ?? [],
    );
  }
}

There are different pages for each type of Item and i want to be able to show only the desired type but I don't know how to use something similar to indexWhere() that will allow me to chose several different ones, because when i impllement it like this

class BitemGridView extends StatelessWidget {
  final List<ItemList> items;
  const BitemGridView({
    Key? key,
    required this.items,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
        padding: const EdgeInsets.only(
          left: 20,
          right: 20,
          top: 20,
        ),
        child: GridView.builder(
          itemCount: items
              .where((items) => items.itemType == ItemType.b)
              .length,
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            childAspectRatio: 3 / 4,
            crossAxisCount: 2,
            mainAxisSpacing: 10,
            crossAxisSpacing: 10,
          ),
          itemBuilder: (context, index) {
            final bItem = items[items.indexWhere((element) => element.itemType == ItemType.b)];
            return BItemThumbnail(bitem: bItem);
            );
          },
        ));

I of course get the proper amount of items on the page, but only the same item that amount of times. I have tried some different forms of for loops to try and make it change the index but after 9 hours of trying to figure this out, I realized my noob self is not going to find the answer.

Is there a way to make the index work? or something that can make it continue to search for indexes where the condition is met for the builder?

1 Answers

indexWhere returns the first index in the list that satisfies the provided test.

The following line will always find the first item that corresponds to your query.

final bItem = items[items.indexWhere((element) => element.itemType == ItemType.b)];

Instead, I would suggest simplifying your code using a basic GridView without builder:

@override
Widget build(BuildContext context) {
  return Padding(
    padding: const EdgeInsets.only(
      left: 20,
      right: 20,
      top: 20,
    ),
    child: GridView(
      children: items
        .where((items) => items.itemType == ItemType.b)
        .map((item) => BItemThumbnail(bitem: bItem))
        .toList(),
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        childAspectRatio: 3 / 4,
        crossAxisCount: 2,
        mainAxisSpacing: 10,
        crossAxisSpacing: 10,
      ),
    ),
  );
}
Related