Home > front end >  How to give border color on click to card in Flutter?
How to give border color on click to card in Flutter?

Time:11-21

ListView(
            scrollDirection: Axis.horizontal,
            children: [
              GestureDetector(
                onTap: () {
                  setState(() {
                    selectedCard = index;
                  });
                },
                child: Card(
                  elevation: 5,
                  shape: RoundedRectangleBorder(
                    side: BorderSide(
                      color: selectedCard == index
                          ? Colors.red
                          : Colors.transparent,
                      width: 2.0,
                    ),
                    borderRadius: BorderRadius.circular(8.0),
                  ),
                  child: Padding(
                    padding: const EdgeInsets.symmetric(
                      horizontal: 20,
                    ),
                    child: Center(
                        child: Text(
                      'Painting',
                      style: artStyle,
                    )),
                  ),
                ),

How can I show any color border like blue, red when a card is clicked, and when clicking another card, how do I make the border around the first clicked card disappear and move to the next?

CodePudding user response:

First define new variable out of build method like this:

int selectedCard = -1;

then in your listview item builder do this:

GestureDetector(
            onTap: () {
              setState(() {
                  selectedCard = 0;
              });
            },
            child: Card(
               shape: StadiumBorder(
                  side: BorderSide(
                     color: selectedCard == 0 ? Colors.red : Colors.transparent,
                     width: 2.0,
                  ),
                ),
                elevation: 5,
                borderOnForeground: true,
                shadowColor: Colors.transparent,
                child: Center(
                   child: Text(
                      'Photorealism',
                ),
              ),
            ),
          ),

for your next item in your list set selectedCard = 1; in setstate and also color: selectedCard == 1 and repeat this for all cards.

full example code:

class TestingDesign2 extends StatefulWidget {
  const TestingDesign2({super.key});

  @override
  State<TestingDesign2> createState() => _TestingDesign2State();
}

class _TestingDesign2State extends State<TestingDesign2> {

  int selectedCard = -1;

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: [
          SizedBox(
            height: 50,
            child: ListView(
              scrollDirection: Axis.horizontal,
              children: [
                GestureDetector(
                  onTap: () {
                    setState(() {
                      selectedCard = 0;
                    });
                  },
                  child: Card(
                    elevation: 5,
                    shape: RoundedRectangleBorder(
                      side: BorderSide(
                        color:
                            selectedCard == 0 ? Colors.red : Colors.transparent,
                        width: 2.0,
                      ),
                      borderRadius: BorderRadius.circular(8.0),
                    ),
                    child: Padding(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 20,
                      ),
                      child: Center(
                          child: Text(
                        'Painting 1',
                      )),
                    ),
                  ),
                ),
                GestureDetector(
                  onTap: () {
                    setState(() {
                      selectedCard = 1;
                    });
                  },
                  child: Card(
                    elevation: 5,
                    shape: RoundedRectangleBorder(
                      side: BorderSide(
                        color:
                            selectedCard == 1 ? Colors.red : Colors.transparent,
                        width: 2.0,
                      ),
                      borderRadius: BorderRadius.circular(8.0),
                    ),
                    child: Padding(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 20,
                      ),
                      child: Center(
                          child: Text(
                        'Painting 2',
                      )),
                    ),
                  ),
                ),
                GestureDetector(
                  onTap: () {
                    setState(() {
                      selectedCard = 2;
                    });
                  },
                  child: Card(
                    elevation: 5,
                    shape: RoundedRectangleBorder(
                      side: BorderSide(
                        color:
                            selectedCard == 2 ? Colors.red : Colors.transparent,
                        width: 2.0,
                      ),
                      borderRadius: BorderRadius.circular(8.0),
                    ),
                    child: Padding(
                      padding: const EdgeInsets.symmetric(
                        horizontal: 20,
                      ),
                      child: Center(
                          child: Text(
                        'Painting 3',
                      )),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

enter image description here

CodePudding user response:

You need to assign hardcoded index of each children items when tapping on the each listview item. Also, I have optimized your code by replacing the Center and the Padding widget with a Container which fulfils your requirement.

Complete code:

import 'package:flutter/material.dart';

void main() {
  runApp(const HomePage());
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _selectedIndex = -1; // to keep the currently clicked item's index

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(),
        body: ListView(
          scrollDirection: Axis.horizontal,
          children: [
            GestureDetector(
              onTap: () {
                setState(() {
                  _selectedIndex = _selectedIndex == 0
                      ? -1
                      : 0; // remove currently selected item's index if same item clicked else assign the index of other clicked item
                });
              },
              child: Card(
                shape: _selectedIndex == 0
                    ? const RoundedRectangleBorder(
                        side: BorderSide(
                          color: Colors.deepPurpleAccent,
                        ),
                      )
                    : null,
                elevation: 5,
                child: Container(
                  alignment: Alignment.center,
                  padding: const EdgeInsets.symmetric(horizontal: 20),
                  child: const Text(
                    'Photorealism',
                    // style: artStyle,
                  ),
                ),
              ),
            ),
            GestureDetector(
              onTap: () {
                setState(() {
                  _selectedIndex = _selectedIndex == 1
                      ? -1
                      : 1; // remove currently selected item's index if same item clicked else assign the index of other clicked item
                });
              },
              child: Card(
                shape: _selectedIndex == 1
                    ? const RoundedRectangleBorder(
                        side: BorderSide(
                          color: Colors.deepPurpleAccent,
                        ),
                      )
                    : null,
                elevation: 5,
                child: Container(
                  alignment: Alignment.center,
                  padding: const EdgeInsets.symmetric(horizontal: 20),
                  child: const Text(
                    'Video',
                    // style: artStyle,
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Output:

CodePudding user response:

import 'package:flutter/material.dart';

void main() {
  runApp(
    const MaterialApp(home: MyApp()
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  static const String _title = 'Flutter Code Sample';
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: Scaffold(
        appBar: AppBar(title: const Text(_title)),
        body: const MyStatefulWidget(),
      ),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({super.key});
  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  int selectedCard = 0;
  var artStyle =  const TextStyle(fontSize: 14.0);
    
  @override
  Widget build(BuildContext context) {
    return  ListView(
        scrollDirection: Axis.horizontal,
        children: [
          GestureDetector(
            onTap: () {
              setState(() {
                  selectedCard = 1; 
                });
            },
            child: Card(
              elevation: 5,
              shape: RoundedRectangleBorder(
                side: BorderSide(
                  color: selectedCard == 1
                      ? Colors.red
                      : Colors.transparent,
                  width: 2.0,
                ),
                borderRadius: BorderRadius.circular(8.0),
              ),
              child: Padding(
                padding: const EdgeInsets.symmetric(
                  horizontal: 20,
                ),
                child: Center(
                    child: Text(
                      'Painting',
                   style: artStyle,
                )),
              ),
            ),
          ),
          GestureDetector(
            onTap: () {
              setState(() {
                  selectedCard = 2; 
                });
            },
            child: Card(
              elevation: 5,
              shape: RoundedRectangleBorder(
                side: BorderSide(
                  color: selectedCard == 2
                      ? Colors.red
                      : Colors.transparent,
                  width: 2.0,
                ),
                borderRadius: BorderRadius.circular(8.0),
              ),
              child: Padding(
                padding: const EdgeInsets.symmetric(
                  horizontal: 20,
                ),
                child: Center(
                    child: Text(
                      'Painting',
                   style: artStyle,
                )),
              ),
            ),
          ),
        ],
     );
    
  }
}

Gist: Complete code here. You may copy & paste the code on dartpad to see the result

  • Related