Jsoon
Jsoon

Reputation: 153

Flutter: Select effect on items in Grid View Builder

How can I change the color of the CARD widget if one of the gridview items is clicked and then the CARD changes color? But you can only choose one item. How do I make it?

Widget listDenomPulsa(AsyncSnapshot <List<Payload>> snapshot) {
    return GridView.builder(
        shrinkWrap: false,
        scrollDirection: Axis.vertical,
        itemCount: snapshot.data.length,
        gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          childAspectRatio: MediaQuery.of(context).size.width / (MediaQuery.of(context).size.height / 3),
        ),
        itemBuilder: (BuildContext context, int index) {
          bool _selectItem = false;
          return GestureDetector(
            onTap: () {
              setState(() {
                  _selectItem = true;
              });
            },
            child: Card(
              color: _selectItem ? Colors.blue:Colors.amber,
              child: Container(
                height: SizeConfig.heightMultiplier * 3,
                child: Padding(
                  padding: EdgeInsets.all(SizeConfig.heightMultiplier * 3),
                  child: Text(
                    snapshot.data[index].desc,
                    style: AppTheme.styleSubTitleBlackSmall,
                  ),
                ),
              ),
            ),
          );
        }
    );
  }

Upvotes: 4

Views: 9006

Answers (2)

Triệu Đ&#244; La
Triệu Đ&#244; La

Reputation: 2481

This is my code, I use Visibility widget to select item

Init

  bool _isLoading = true;
  bool _isSelectionMode = false;
  int _totalImage = 0;
  List<AssetEntity>? _entities;
  final Set<int> _listSelected = {};

Code

    @override
  Widget build(BuildContext context) {
    if (_isLoading) {
      return const Center(child: CircularProgressIndicator.adaptive());
    } else {
      if (_totalImage == -1) {
        return const Center(child: Text("Permission is not accessible."));
      }
      if (_totalImage == 0) {
        return const Center(child: Text("No image/video on device"));
      } else {
        return GridView.builder(
          itemCount: _entities!.length,
          shrinkWrap: false,
          scrollDirection: Axis.vertical,
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 4,
            /*mainAxisSpacing: 1,
            crossAxisSpacing: 1,*/
          ),
          itemBuilder: (BuildContext context, int index) {
            final AssetEntity entity = _entities![index];
            return Material(
              child: InkWell(
                onTap: () {
                  if (_isSelectionMode) {
                    setState(() {
                      developer.log('${_listSelected.contains(index)}',
                          name: 'Click');
                      if (_listSelected.contains(index)) {
                        _listSelected.remove(index);
                      } else {
                        _listSelected.add(index);
                      }
                    });
                  }
                },
                onLongPress: () {
                  if (_isSelectionMode) return;
                  _isSelectionMode = true;
                  setState(() {
                    developer.log('${_listSelected.contains(index)}',
                        name: 'Click');
                    if (_listSelected.contains(index)) {
                      _listSelected.remove(index);
                    } else {
                      _listSelected.add(index);
                    }
                  });
                },
                child: Card(
                  child: Stack(
                    alignment: AlignmentDirectional.center,
                    fit: StackFit.expand,
                    children: [
                      AssetEntityImage(entity, fit: BoxFit.cover),
                      Visibility(
                        visible: _listSelected.contains(index),
                        child: const Icon(
                          Icons.check_circle,
                          color: Colors.green,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            );
          },
          findChildIndexCallback: (Key key) {
            // Re-use elements.
            if (key is ValueKey<int>) {
              return key.value;
            }
            return null;
          },
        );
      }
    }
  }

Upvotes: 0

timilehinjegede
timilehinjegede

Reputation: 14043

This would work perfectly. Check the code below:

class MyGridView extends StatefulWidget {
  @override
  _MyGridViewState createState() => _MyGridViewState();
}

class _MyGridViewState extends State<MyGridView> {

  // Set an int with value -1 since no card has been selected
  int selectedCard = -1;

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
        shrinkWrap: false,
        scrollDirection: Axis.vertical,
        itemCount: 10,
        gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          childAspectRatio: MediaQuery.of(context).size.width /
              (MediaQuery.of(context).size.height / 3),
        ),
        itemBuilder: (BuildContext context, int index) {
          return GestureDetector(
            onTap: () {
              setState(() {
                // Ontap of each card, set the defined int to the grid view index
                selectedCard = index;
              });
            },
            child: Card(
              // Check if the index is equal to the selected Card integer
              color: selectedCard == index ? Colors.blue : Colors.amber,
              child: Container(
                height: 200,
                width: 200,
                child: Center(
                  child: Text(
                    '$index',
                    style: TextStyle(
                      fontSize: 20,
                      color: Colors.white,
                      fontWeight: FontWeight.w500,
                    ),
                  ),
                ),
              ),
            ),
          );
        });
  }
}

Output:

Enter image description here

Enter image description here

Upvotes: 10

Related Questions