Home > Software design >  How to change the border colour of a card upon tapping it wrapped in listview.builder in flutter?
How to change the border colour of a card upon tapping it wrapped in listview.builder in flutter?

Time:04-15

I am fetching certain details from firebase and showing them in the form of card, with the help of ListView.Builder. Now, upon tapping a specific card I want to change its border colour to green. I have tried using the flag variable in the setState but it sets the border colour for every card to green. Someone pls have a look at the code I've pasted, and let me know what should be done.This is the image of the UI

Thank You:)

 StreamBuilder<QuerySnapshot>(
        stream: collectionTests.snapshots(),
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            return const Text("Something went wrong");
          }
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(
              child: CircularProgressIndicator(),
            );
          } else {
            final myDocs = snapshot.data!.docs;
            try {
              return ListView.builder(
                itemCount: myDocs.length,
                itemBuilder: (context, index) {
                  return Padding(
                    padding: const EdgeInsets.fromLTRB(17, 11, 17, 11),
                    child: InkWell(
                      onTap: () {},
                      child: Card(
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(15),
                          side: const BorderSide(
                            color: Colors.white,
                          ),
                        ),
                        child: ListTile(
                          contentPadding: const EdgeInsets.all(8),
                          title: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                myDocs[index]['name'],
                                style: const TextStyle(
                                  fontSize: 22,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                              Card(
                                color: Colors.indigo,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(5),
                                ),
                                child: Padding(
                                  padding: const EdgeInsets.all(8.0),
                                  child: Text(
                                    myDocs[index]['price'],
                                    style: const TextStyle(
                                      color: Colors.white,
                                      fontStyle: FontStyle.italic,
                                      fontSize: 20,
                                    ),
                                  ),
                                ),
                              )
                            ],
                          ),
                          subtitle: Padding(
                            padding: const EdgeInsets.fromLTRB(8, 8, 12, 8),
                            child: Text(
                              myDocs[index]['description'],
                              style: const TextStyle(
                                fontSize: 18,
                              ),
                            ),
                          ),
                        ),
                      ),
                    ),
                  );
                },
              );
            } catch (e) {
              return const Center(
                child: Card(
                  child: Text(
                    'Something went wrong, please check your connection',
                    style: TextStyle(
                      fontSize: 18,
                      color: Colors.black,
                    ),
                  ),
                ),
              );
            }
          }
        },
      ),   

CodePudding user response:

Extract your widget into a new stateful class and call the class inside the ListView.

main.dart

import 'package:flutter/material.dart';
import 'package:stackoverflow/custom_card.dart';

void main(){
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: ListView.builder(
          itemCount: 5,
          itemBuilder: (context, i){
            return CustomCard();
          },
        ),
      ),
    );
  }
}

custom_card.dart

import 'package:flutter/material.dart';

class CustomCard extends StatefulWidget {
  const CustomCard({Key? key}) : super(key: key);

  @override
  _CustomCardState createState() => _CustomCardState();
}

class _CustomCardState extends State<CustomCard> {

  Color borderColor = Colors.black;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: double.infinity,
      height: 100,
      child: GestureDetector(
        onTap: (){
          setState(() {
            borderColor = Colors.green;
          });
        },
        child: Card(
          color: borderColor,
        ),
      ),
    );
  }
}

CodePudding user response:

Firstly, you need to define a list that contains bool variables out of build method. These variables will decide whether the border of relevant card is white or green.

List<bool> bordersColors = [];

Then in your listview like this;

return ListView.builder(
                itemCount: myDocs.length,
                itemBuilder: (context, index) {
                  bordersColors.add(false);
                  return Padding(
                    padding: const EdgeInsets.fromLTRB(17, 11, 17, 11),
                    child: InkWell(
                      onTap: () {
                          setState((){
                               bordersColors[index] = true;
                           })
                        },
                      child: Card(
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(15),
                          side: const BorderSide(
                            color: bordersColors[index] ? Colors.green : Colors.white,
                          ),
                        ),
                        child: ListTile(
                          contentPadding: const EdgeInsets.all(8),
                          title: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text(
                                myDocs[index]['name'],
                                style: const TextStyle(
                                  fontSize: 22,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                              Card(
                                color: Colors.indigo,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(5),
                                ),
                                child: Padding(
                                  padding: const EdgeInsets.all(8.0),
                                  child: Text(
                                    myDocs[index]['price'],
                                    style: const TextStyle(
                                      color: Colors.white,
                                      fontStyle: FontStyle.italic,
                                      fontSize: 20,
                                    ),
                                  ),
                                ),
                              )
                            ],
                          ),
                          subtitle: Padding(
                            padding: const EdgeInsets.fromLTRB(8, 8, 12, 8),
                            child: Text(
                              myDocs[index]['description'],
                              style: const TextStyle(
                                fontSize: 18,
                              ),
                            ),
                          ),
                        ),
                      ),
                    ),
                  );
                },
              );
            } catch (e) {
              return const Center(
                child: Card(
                  child: Text(
                    'Something went wrong, please check your connection',
                    style: TextStyle(
                      fontSize: 18,
                      color: Colors.black,
                    ),
                  ),
                ),
              );
  • Related