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',
)),
),
),
),
],
),
),
],
),
);
}
}
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