Reputation: 131
Hello. I was stuck for some time with this problem but I achieved what is shown in the gif with the following code:
class _EntitiesState extends State<Entities> {
bool selected = false;
bool selected2 = false;
bool selected3 = false;
var xwidth = 1;
final activeColor = Colors.red;
var flex1 = 1;
var flex2 = 1;
var flex3 = 1;
@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
flex: flex1,
child: GestureDetector(
onTap: () => {
setState(() {
flex1 = 0;
flex2 = 1;
flex3 = 1;
selected3 = !selected3;
})
},
child: AnimatedContainer(
color: selected3 ? activeColor : Colors.green,
width: MediaQuery.of(context).size.width *
(selected3 ? xwidth : 0.33),
duration: const Duration(seconds: 1),
child: Container(),
),
),
),
Expanded(
flex: flex2,
child: GestureDetector(
onTap: () => {
setState(() {
flex1 = 1;
flex2 = 0;
flex3 = 1;
selected2 = !selected2;
})
},
child: AnimatedContainer(
color: selected2 ? activeColor : Colors.yellow,
width: MediaQuery.of(context).size.width *
(selected2 ? xwidth : 0.33),
duration: const Duration(seconds: 1),
child: Container(),
),
),
),
Expanded(
flex: flex3,
child: GestureDetector(
onTap: () => {
setState(() {
flex1 = 1;
flex2 = 1;
flex3 = 0;
selected = !selected;
})
},
child: AnimatedContainer(
color: selected ? activeColor : Colors.blue,
width: MediaQuery.of(context).size.width *
(selected ? xwidth : 0.33),
duration: const Duration(seconds: 1),
child: Container(),
),
),
),
],
);
}
}
I have a question. Is there a better, more elegant way to do this? Maybe there is a suitable flutter element that does it? My solution is kinda primitive and doesn't work well with a lot of expandable rows.
Upvotes: 1
Views: 64
Reputation: 63829
It can be simplified using nullable selectedIndex, int? selectedIndex;
.
Container
s color and width
logic will be
color: selectedIndex == null && selectedIndex == index
? Colors.red
: colors[index],
width: selectedIndex == null
? constraints.maxWidth / totalItem
: selectedIndex == index
? constraints.maxWidth
: 0,
And index selection logic will be
onTap: () {
selectedIndex == null
? selectedIndex = index
: selectedIndex = null;
setState(() {});
},
Run on dartPad
class Entities extends StatefulWidget {
const Entities({Key? key}) : super(key: key);
@override
State<Entities> createState() => _EntitiesState();
}
class _EntitiesState extends State<Entities> {
int? selectedIndex;
int totalItem = 3;
late List<Color> colors;
@override
void initState() {
colors = List.generate(
totalItem,
(index) =>
Color((Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0));
super.initState();
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) => Row(
children: List.generate(
totalItem,
(index) => GestureDetector(
onTap: () {
selectedIndex == null
? selectedIndex = index
: selectedIndex = null;
setState(() {});
},
child: AnimatedContainer(
key: ValueKey(index),
height: constraints.maxHeight,
color: selectedIndex == null && selectedIndex == index
? Colors.red
: colors[index],
width: selectedIndex == null
? constraints.maxWidth / totalItem
: selectedIndex == index
? constraints.maxWidth
: 0,
duration: const Duration(seconds: 1),
alignment: Alignment.center,
child: Text("$index"),
),
),
),
),
);
}
}
Upvotes: 1