I have created an app with multiple buttons with some adjusting counters and others adjusting bools. (for widget visibility) these buttons have been prebuilt in stateless their own dart file that I can then call on. the problem I'm having is all my setState functions are very similar but with only slight changes. which is making my code very long. Is there a way to tidy this up and have the ontap in the stateless widgets and the setstates in a seperate dart file I can then call on?
here is my main page:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'test2.dart';
class TestMain extends StatefulWidget {
const TestMain({Key? key}) : super(key: key);
@override
State<TestMain> createState() => _TestMainState();
}
class _TestMainState extends State<TestMain> {
int localCounter1 = 0;
int localCounter2 = 0;
int globalCounter = 0;
bool bool1 = false;
bool bool2 = false;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
CounterAndButtons(
minusButton: InkWell(
onTap: () {
setState(() {
if (localCounter1 <= 0) return;
if (localCounter1 > 0) localCounter1--;
if (globalCounter > 0) globalCounter--;
});
},
child: PlusMinusButton(
icon: CupertinoIcons.minus,
bgColor: Colors.blueGrey,
iconColor: Colors.white),
),
counter: Counter(counter: '$localCounter1'),
plusButton: InkWell(
onTap: () {
setState(() {
if (globalCounter >= 12) return;
if (localCounter1 < 12) localCounter1 ;
if (globalCounter < 12) globalCounter ;
});
},
child: PlusMinusButton(
icon: CupertinoIcons.plus,
bgColor: Colors.blueGrey,
iconColor: Colors.white),
),
),
SizedBox(
height: 20,
),
CounterAndButtons(
minusButton: InkWell(
onTap: () {
setState(() {
if (localCounter2 <= 0) return;
if (localCounter2 > 0) localCounter2--;
if (globalCounter > 0) globalCounter--;
});
},
child: PlusMinusButton(
icon: CupertinoIcons.minus,
bgColor: Colors.blueGrey,
iconColor: Colors.white),
),
counter: Counter(counter: '$localCounter2'),
plusButton: InkWell(
onTap: () {
setState(() {
if (globalCounter >= 12) return;
if (localCounter2 < 12) localCounter2 ;
if (globalCounter < 12) globalCounter ;
});
},
child: PlusMinusButton(
icon: CupertinoIcons.plus,
bgColor: Colors.blueGrey,
iconColor: Colors.white),
),
),
SizedBox(
height: 20,
),
Counter(counter: '$globalCounter'),
SizedBox(
height: 20,
),
InkWell(
onTap: () {
setState(() {
bool1 = true;
bool2 = true;
});
},
child: NormalButtons(
tpNumber: 'button Text',
boxColor: Colors.blueGrey,
textColor: Colors.white),
),
],
),
);
}
}
and here is my stateless class widgets that i call on:
import 'package:flutter/material.dart';
class PlusMinusButton extends StatelessWidget {
PlusMinusButton(
{required this.icon, required this.bgColor, required this.iconColor});
final Color bgColor;
final Color iconColor;
final IconData icon;
@override
Widget build(BuildContext context) {
return Container(
constraints: BoxConstraints(
minWidth: 30,
maxWidth: 80,
minHeight: 80,
maxHeight: 80,
),
margin: EdgeInsets.all(9),
decoration: BoxDecoration(
color: bgColor,
borderRadius: BorderRadius.circular(10),
),
child: FittedBox(
fit: BoxFit.scaleDown,
child: Icon(
icon,
color: iconColor,
),
),
);
}
}
class CounterAndButtons extends StatelessWidget {
CounterAndButtons(
{required this.minusButton,
required this.counter,
required this.plusButton});
final Widget minusButton;
final Widget counter;
final Widget plusButton;
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
minusButton,
counter,
plusButton,
],
);
}
}
class Counter extends StatelessWidget {
Counter({required this.counter});
final String counter;
@override
Widget build(BuildContext context) {
return Text(
counter,
style: TextStyle(fontSize: 60),
maxLines: 1,
);
}
}
class NormalButtons extends StatelessWidget {
NormalButtons(
{required this.tpNumber,
required this.boxColor,
required this.textColor});
final String tpNumber;
final Color boxColor;
final Color textColor;
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(horizontal: 5, vertical: 8),
padding: EdgeInsets.all(3),
decoration: BoxDecoration(
color: boxColor,
borderRadius: BorderRadius.circular(10),
),
child: Center(
child: Text(
tpNumber,
style: TextStyle(color: textColor, fontSize: 80),
textAlign: TextAlign.center,
maxLines: 2,
),
),
);
}
}
CodePudding user response:
You can pass onTap as a parameter to your PlusMinusButton like this :
class PlusMinusButton extends StatelessWidget {
PlusMinusButton({required this.icon, required this.bgColor, required this.iconColor, this.onTap});
final Color bgColor;
final Color iconColor;
final IconData icon;
final VoidCallback? onTap;
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
child: Container(
constraints: BoxConstraints(
minWidth: 30,
maxWidth: 80,
minHeight: 80,
maxHeight: 80,
),
margin: EdgeInsets.all(9),
decoration: BoxDecoration(
color: bgColor,
borderRadius: BorderRadius.circular(10),
),
child: FittedBox(
fit: BoxFit.scaleDown,
child: Icon(
icon,
color: iconColor,
),
),
),
);
}
}
In your main file :
PlusMinusButton(
onTap: () {
setState(() {
if (localCounter1 <= 0) return;
if (localCounter1 > 0) localCounter1--;
if (globalCounter > 0) globalCounter--;
});
},
icon: CupertinoIcons.minus,
bgColor: Colors.blueGrey,
iconColor: Colors.white)