Why does Flutter GridView display the wrong images after correctly removing an item?

Viewed 30

I have a GridView.builder that displays images from an array called _storyAssets. If I remove one of the images, the array is updated correctly, BUT the view is NOT. Even though the array that is passed to the GridView.builder is correct, the image that I removed remains on the screen and ONLY the last image in the view is removed. When I inspect the individual items being sent to the GridView, they are correct. The removed item is NOT in the data, but it is still visible on screen, while the last item that GridView builds that should still be visible is not.

Here is my remove function:

  void removeAsset(tourAsset) {
final List<TourAsset> tempArray = [];
_storyAssets.forEach((item) {
  if (item.ref != tourAsset.ref) {
    tempArray.add(item);
  }
});
setState(() {
  _storyAssets = tempArray;
});

}

Here's the GridView.builder:

GridView.builder(
                    itemCount: _storyAssets.length,
                    shrinkWrap: true,
                    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                      // crossAxisCount: 1
                      crossAxisCount: _storyAssets.length <= 1 ? 1 : 2,
                    ),
                    itemBuilder: (context, index) {
                      print(
                          'GridView Story Asset: ${_storyAssets[index].ref} ');
                      return Align(
                        alignment: Alignment.topLeft,
                        child: Container(
                          width: 200,
                          height: 200,
                          child: AssetThumbnail(
                            onTap: removeAsset,
                            asset: _storyAssets[index],
                          ),
                        ),
                      );
                    })

Here are my print statements that show the correct item was removed. NOTE that the bike image is still showing in the print statements when the GridView builds, but is not visible on screen:

I/flutter ( 5800): 1. asset being removed: media/RvoGlxBvpUY1sg6vi5KA5guDzVn1/5c8513a2-e89b-4a3e-ad53-746282d79f08 I/flutter ( 5800): 2.forEach item: media/RvoGlxBvpUY1sg6vi5KA5guDzVn1/77300f96-b551-4dc7-b73a-769fdfd6485e removing: media/RvoGlxBvpUY1sg6vi5KA5guDzVn1/5c8513a2-e89b-4a3e-ad53-746282d79f08 I/flutter ( 5800): 2.forEach item: media/RvoGlxBvpUY1sg6vi5KA5guDzVn1/5c8513a2-e89b-4a3e-ad53-746282d79f08 removing: media/RvoGlxBvpUY1sg6vi5KA5guDzVn1/5c8513a2-e89b-4a3e-ad53-746282d79f08 I/flutter ( 5800): 2.forEach item: tours/1QRxJQKKXJhaHqkyh5vK/hue_cyclo_tour.jpg removing: media/RvoGlxBvpUY1sg6vi5KA5guDzVn1/5c8513a2-e89b-4a3e-ad53-746282d79f08 I/flutter ( 5800): 3. storyAssets array before removal: I/flutter ( 5800): media/RvoGlxBvpUY1sg6vi5KA5guDzVn1/77300f96-b551-4dc7-b73a-769fdfd6485e I/flutter ( 5800): media/RvoGlxBvpUY1sg6vi5KA5guDzVn1/5c8513a2-e89b-4a3e-ad53-746282d79f08 I/flutter ( 5800): tours/1QRxJQKKXJhaHqkyh5vK/hue_cyclo_tour.jpg I/flutter ( 5800): 4. temp array: I/flutter ( 5800): media/RvoGlxBvpUY1sg6vi5KA5guDzVn1/77300f96-b551-4dc7-b73a-769fdfd6485e I/flutter ( 5800): tours/1QRxJQKKXJhaHqkyh5vK/hue_cyclo_tour.jpg I/flutter ( 5800): ^^^^^^^STORY EDITOR^^^^^^^^ I/flutter ( 5800): 5. storyAssets in the build: I/flutter ( 5800): media/RvoGlxBvpUY1sg6vi5KA5guDzVn1/77300f96-b551-4dc7-b73a-769fdfd6485e I/flutter ( 5800): tours/1QRxJQKKXJhaHqkyh5vK/hue_cyclo_tour.jpg I/flutter ( 5800): GridView Story Asset: media/RvoGlxBvpUY1sg6vi5KA5guDzVn1/77300f96-b551-4dc7-b73a-769fdfd6485e I/flutter ( 5800): GridView Story Asset: tours/1QRxJQKKXJhaHqkyh5vK/hue_cyclo_tour.jpg

Here are screen shots. The item that I removed ends in 08. The bicycle image should still be visible, but is not: enter image description here

enter image description here

1 Answers

Although you don't provide the code for the AssetThumbnail the problem you describe sounds like a Widget Key problem, which is common if you use Stateful widgets in a collection.

Instead of calling AssetThumbnail(onTap: removeAsset, asset: _storyAssets[index]) try AssetThumbnail(key: ObjectKey(_storyAssets[index]), onTap: removeAsset, asset: _storyAssets[index])

The key associates the thumbnail widget with the actual contents. This article explains it well.

Related