I wanna add effect on button ,like while we press the button , background color of button should get change to transparent and button borderline color should be enable, then we release the button , background color get back into yellow color and borderline color should get disable.
Here is some code which I tried button but It doesn't work properly.
class CustomButton extends StatefulWidget {
final void Function()? onPressed;
final String lable;
final int backgroundColor;
final Color textColor;
final FontWeight fontWeight;
final EdgeInsetsGeometry margin;
const CustomButton(
{Key? key,
required this.onPressed,
required this.lable,
required this.backgroundColor,
this.textColor = Colors.black,
this.fontWeight = FontWeight.bold,
this.margin = EdgeInsets.zero})
: super(key: key);
#override
State<CustomButton> createState() => _CustomButtonState();
}
class _CustomButtonState extends State<CustomButton> {
bool isColorChanged = false;
#override
Widget build(BuildContext context) {
AppSize appSize = AppSize(context);
return GestureDetector(
onLongPress: () {
setState(() {
isColorChanged = true;
});
},
onLongPressCancel: () {
setState(() {
isColorChanged = false;
});
},
onTap: widget.onPressed,
child: Container(
margin: widget.margin,
height: isMobile(context) ? appSize.scaledHeight(0.065) : 80,
alignment: Alignment.center,
decoration: BoxDecoration(
color: isColorChanged
? Colors.transparent
: Color(widget.backgroundColor),
borderRadius: BorderRadius.all(Radius.circular(isMobile(context)
? 8
: 15) // <--- border radius here
),
border: Border.all(
color:
isColorChanged ? Color(themeColor) : Colors.transparent)),
padding: EdgeInsets.fromLTRB(20, 1, 20, 1),
child: Text(
widget.lable,
style: TextStyle(
fontSize: isMobile(context)
? MyFontSize().mediumTextSizeMobile
: MyFontSize().mediumTextSizeTablet,
color: widget.textColor,
fontWeight: widget.fontWeight),
),
// child:
),
);
}
}
Using Button :
class ExampleView extends StatelessWidget {
const ExampleView({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: CustomButton(
onPressed: () {},
lable: StringFile.service_provider.toUpperCase(),
backgroundColor: colorYellowBtn),
),
);
}
}
before :
while we press the button:
when we release the button :
You can create a custom widget and use GestureDetector (onTapDown, onTapUp events to change color) with AnimatedContainer (to animate the color)
Try below code hope its help to you.
Refer ElevatedButton
Refer MaterialStateProperty
ElevatedButton(
child: Text(
'Service Provider'.toUpperCase(),
style: TextStyle(
color: Colors.black,
),
),
onPressed: () {
print('Pressed');
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed)) return Colors.teal;
return Colors.yellow;
},
),
),
),
After and before pressed result->
when you pressed the button result->
Try this :
RaisedButton(
onPressed: () {},
child: Text("Test"),
highlightColor: YOUR_PRESSED_COLOR, //Replace with actual colors
color: IDLE_STATE_COLOR,
),
ElevatedButton(
child: Text('Elevated Button', style: TextStyle(color: Colors.black),),
onPressed: () {
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed)) return Colors.white;
return Colors.yellow;
},
),
),
)
You can use like this.
Related
how can i change color of these iconbuttons by pressing it, please help me and show me whole code for it,
Thanks
In setState you have to add boolean variable, for example changeColor = false;
Then in button :
color: changeColor ? Colors.grey : Colors.blue,
onPressed: () => setState(() => changeColor = !changeColor),
Flutter - How do I toggle the color of a RaisedButton upon click?
This is new method to change color,
there is youtube video for this Here and a article for this Article
ElevatedButton(
child: Text('Elevated Button'),
onPressed: () {
print('Pressed');
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed)) return Colors.green;
return Colors.greenAccent;
},
),
),
)
You can change the background color of the ElevatedButton using MaterialStateProperty class. You can change the color of the button based on the states too. See the code snippet given below.
IconButton in flutter has a color variable you can set as here:
IconButton(
color: Colors.green,
icon: Icon(Icons.camera),
onPressed: () {},
)
This is the code that I would use:
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: MyWidget(),
);
}
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: SingleChildScrollView(
child: Column(children: [
const Text(
'Choose Category',
style: TextStyle(
color: Colors.white,
fontSize: 12,
fontWeight: FontWeight.w600,
),
),
Row(children: [
CategoryButton(
svg: 'assets/candy.svg',
label: 'Tech',
selected: false,
),
CategoryButton(
svg: 'assets/candy.svg',
label: 'Finance',
selected: false,
),
CategoryButton(
svg: 'assets/candy.svg',
label: 'Design',
selected: false,
),
CategoryButton(
svg: 'assets/candy.svg',
label: 'File',
selected: false,
),
CategoryButton(
svg: 'assets/candy.svg',
label: 'Music',
selected: false,
),
])
]),
),
),
);
}
}
class CategoryButton extends StatefulWidget {
CategoryButton({
Key? key,
required this.svg,
required this.label,
required this.selected,
}) : super(key: key);
String svg;
String label;
bool selected;
#override
State<CategoryButton> createState() => _CategoryButtonState();
}
class _CategoryButtonState extends State<CategoryButton> {
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
widget.selected = !widget.selected;
});
print(widget.selected);
},
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
color: widget.selected ? Colors.blue : Colors.black,
borderRadius: BorderRadius.circular(90),
),
child: Column(
children: [
SvgPicture.asset(widget.svg,
color: widget.selected ? Colors.white : Colors.blue),
Text(
widget.label,
style: TextStyle(
color: Colors.white,
fontSize: 9,
fontWeight: FontWeight.w500,
),
),
],
)),
);
}
}
here you need to make sure to add flutter_svg to your pubspec.yaml file and have a folder for your assets and add that to your pubspec.yaml file as well
if you have any further questions just ask :)
I have six buttons on the screen and they all do the same function. But I want to control the colors of these buttons to be clicked. If the button is clicked, the button color should be green (I'm doing this buttonColorDisable.) Everything is normal so far, but in _buttonFunction() widget.callbackColor(); When I call it, I expect all button colors to change again, but only the last button is affected. Other buttons still remain green. how do i solve this.
class BuildNumButton extends StatefulWidget {
final int number;
final Color color;
final Color buttonColorDisable;
final Function callbackColor;
final Function callbackList;
final Function callbackScore;
final Function callbackTarget;
const BuildNumButton({
Key? key,
required this.number,
required this.callbackScore,
required this.callbackList,
required this.callbackTarget,
required this.callbackColor,
required this.color,
required this.buttonColorDisable,
}) : super(key: key);
#override
State<BuildNumButton> createState() => _BuildNumButtonState();
}
class _BuildNumButtonState extends State<BuildNumButton> {
bool isButtonVisible = false;
void _buttonFunction() {
isButtonVisible = true;
CalculateScore.sumNumbers(widget.number);
CalculateScore.calculateScore();
widget.callbackScore();
if (CalculateScore.answer == true) {
if (!CalculateScore.endGame) {
widget.callbackList();
widget.callbackColor();
isButtonVisible = false;
}
widget.callbackTarget();
}
}
#override
Widget build(BuildContext context) {
return SizedBox(
width: 150,
height: 120,
child: TextButton(
style: ButtonStyle(
backgroundColor: isButtonVisible
? MaterialStateProperty.all(
widget.buttonColorDisable) //button color green
: MaterialStateProperty.all(widget.color),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: const BorderSide(color: Colors.white, width: 3),
),
),
),
onPressed: isButtonVisible ? null : _buttonFunction,
child: Text(
widget.number.toString(),
style: numButtonTextStyle,
),
),
);
}
}
I will prefer creating List<int> to hold tapped index and use BuildNumButton extends StatelessWidget.
Run on dartPad.
class BuildNumButton extends StatelessWidget {
final int number;
final Color color;
final Color buttonColorDisable;
final VoidCallback callback;
final bool isDisable;
const BuildNumButton({
Key? key,
required this.number,
required this.color,
required this.buttonColorDisable,
required this.callback,
required this.isDisable,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return SizedBox(
width: 150,
height: 120,
child: TextButton(
style: ButtonStyle(
backgroundColor: isDisable
? MaterialStateProperty.all(
buttonColorDisable) //button color green
: MaterialStateProperty.all(color),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: const BorderSide(color: Colors.white, width: 3),
),
),
),
onPressed: isDisable ? null : callback,
child: Text(
number.toString(),
),
),
);
}
}
and VoidCallback used to get tapEvent and based on condition update the state.
List<int> disableButtons = [];
.....
...List.generate(
6,
(index) => BuildNumButton(
buttonColorDisable: Colors.green,
isDisable: disableButtons.contains(index),
callback: () {
disableButtons.add(index);
if (disableButtons.length == 6) disableButtons.clear();
setState(() {});
},
color: Colors.cyanAccent,
number: index,
),
)
I have a simple website menu on clicking it's just changing int value and on the basis of int value it's changing the font color.
I don't want to use setState instead of it I need to use getX I am doing it like this
class SideMenu extends StatefulWidget {
const SideMenu({Key? key}) : super(key: key);
#override
_SideMenuState createState() => _SideMenuState();
}
class _SideMenuState extends State<SideMenu> {
TileColorX tcx = Get.put(TileColorX());
#override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
children: [
DrawerHeader(
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Dashboard ',
style: Theme.of(context).textTheme.caption!.copyWith(
color: Colors.white,
fontSize: 21,
fontWeight: FontWeight.w700)),
Text('Dashboard',
style: Theme.of(context).textTheme.caption!.copyWith(
color: primaryColor,
fontSize: 21,
fontWeight: FontWeight.w700)),
],
)),
),
DrawerListTile(
title: "Dashboard",
svgSrc: "assets/icons/menu_dashbord.svg",
control: 0,
press: () {
tcx.toggle(0);
},
),
DrawerListTile(
title: "POS and Invoices",
svgSrc: "assets/icons/menu_tran.svg",
control: 1,
press: () {
tcx.toggle(1);
},
),
],
),
);
}
}
class DrawerListTile extends StatelessWidget {
DrawerListTile({
Key? key,
// For selecting those three line once press "Command+D"
required this.title,
required this.svgSrc,
required this.press,
required this.control,
}) : super(key: key);
final String title, svgSrc;
final VoidCallback press;
final int control;
TileColorX tcx = Get.put(TileColorX());
#override
Widget build(BuildContext context) {
return ListTile(
onTap: press,
horizontalTitleGap: 0.0,
leading: SvgPicture.asset(
svgSrc,
color: control == tcx.selectedIndex.value
? Colors.white
: Colors.white54,
height: 16,
),
title: Text(
title,
style: TextStyle(
color: control == tcx.selectedIndex.value
? Colors.white
: Colors.white54),
),
);
}
}
I have a class for toggle
class TileColorX extends GetxController {
RxInt selectedIndex = 0.obs;
void toggle(int index) => selectedIndex.value = index;
}
But it's not changing the state (mean not changing my font color)
You need to use Obx on that widget you want to see change. This will work
return Obx(() => ListTile(
onTap: press,
horizontalTitleGap: 0.0,
leading: SvgPicture.asset(
svgSrc,
color: control == tcx.selectedIndex.value
? Colors.white
: Colors.white54,
height: 16,
),
title: Text(
title,
style: TextStyle(
color: control == tcx.selectedIndex.value
? Colors.white
: Colors.white54),
),
));
I don't know more detailed answer to what Obx exactly did but it will work for you :D
Hi im working on Flutter web and when i hover flatbutton i wanna change the text color. Its on hover not on pressed. But how do i detect/know its been hovered, so i can manage the state color. Thanks
FlatButton(
color: Colors.white,
textColor: Colors.teal[700], //when hovered text color change
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
side: BorderSide(
color: Colors.teal[700],
),
),
onPressed: () {},
child: Text("Log in"),
),
You can copy paste run full code below
You can use MouseRegion's onHover attribute
code snippet
void _incrementExit(PointerEvent details) {
setState(() {
textColor = Colors.blue;
_exitCounter++;
});
}
void _updateLocation(PointerEvent details) {
setState(() {
textColor = Colors.red;
x = details.position.dx;
y = details.position.dy;
});
}
return MouseRegion(
onEnter: _incrementEnter,
onHover: _updateLocation,
onExit: _incrementExit,
child: FlatButton(
color: Colors.white,
textColor: Colors.teal[700], //when hovered text color change
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
working demo
full code
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
void main() => runApp(MyApp());
/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
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: Center(
child: MyStatefulWidget(),
),
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
#override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
Color textColor = Colors.blue;
int _enterCounter = 0;
int _exitCounter = 0;
double x = 0.0;
double y = 0.0;
void _incrementEnter(PointerEvent details) {
setState(() {
_enterCounter++;
});
}
void _incrementExit(PointerEvent details) {
setState(() {
textColor = Colors.blue;
_exitCounter++;
});
}
void _updateLocation(PointerEvent details) {
setState(() {
textColor = Colors.red;
x = details.position.dx;
y = details.position.dy;
});
}
#override
Widget build(BuildContext context) {
return MouseRegion(
onEnter: _incrementEnter,
onHover: _updateLocation,
onExit: _incrementExit,
child: FlatButton(
color: Colors.white,
textColor: Colors.teal[700], //when hovered text color change
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
side: BorderSide(
color: Colors.teal[700],
),
),
onPressed: () {},
child: Text("Log in", style: TextStyle(color: textColor),),
),
);
}
}
You can change foregroundColor property of Button Style like this:
ElevatedButton.styleFrom().copyWith(
backgroundColor: MaterialStateProperty.resolveWith<Color?>(
(states) {
if (states.contains(MaterialState.hovered)) {
return Colors.blue;
} else if (states.contains(MaterialState.pressed)) {
return Colors.yellow;
}
return Colors.red;
},
),
foregroundColor: MaterialStateProperty.resolveWith<Color?>(
(states) {
if (states.contains(MaterialState.hovered)) {
return Colors.green;
}
return Colors.black;
},
),
);
For the textButton we can use foregroundColor property of ButtonStyle.
TextButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.focused))
return Colors.red;
if (states.contains(MaterialState.hovered))
return Colors.green;
if (states.contains(MaterialState.pressed))
return Colors.blue;
return Colors.yellow; // null throus error in flutter 2.2+.
}),
),
onPressed: () { },
child: Text('TextButton with custom overlay colors'),
)
There's a package that achieves this using MouseRegion too.
https://pub.dev/packages/hovering
Example:
HoverButton(
onpressed: () {
print('test');
},
color: Colors.green,
hoverColor: Colors.red,
hoverTextColor: Colors.blue,
child: Text('test'),
)
Update this might help someone,
instead use
TextButton
here is code example:
TextButton(
onPressed: () {},
style: ButtonStyle(
foregroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.hovered))
return Colors.yellow;
return Colors.blue;
}),
),
child: const Text(
'Text Button ',
style: TextStyle(fontSize: 24),
),
)
How to change the color of button dynamically when user click on the button. The following code generate buttons with random numbers. need to check
for (var j = 0; j < 5; j++) {
rowOfButtons.add(SizedBox(
width: 70,
height: 70,
child: Padding(
padding: EdgeInsets.all(5.0),
child: FlatButton(
color: Colors.blue,
textColor: Colors.white,
disabledColor: Colors.grey,
disabledTextColor: Colors.black,
splashColor: Colors.blueAccent,
onPressed: () {
/*...*/
},
child: Text(
numberlist[addrow].toString(),
style: TextStyle(fontSize: 20.0),
),
))));
addrow++;
count++;
}
It's state. For example, the below widget renders a row of buttons (it accepts an argument number which is an integer - the number of buttons to render).
When you click on a button, it updates sets the state of the index of which button was clicked, changes the color from Red to Blue.
Note: This may not be what you want to do - you may want to highlight all buttons when clicked. That's fine, the concept is that you need to use state to keep track of clicks.
class RowOfButtons extends StatefulWidget {
RowOfButtons({Key key, this.number}) : super(key: key);
final int number;
#override
RowOfButtonsState createState() => RowOfButtonsState();
}
class RowOfButtonsState extends State<RowOfButtons> {
int tapped;
#override
Widget build(BuildContext context) {
List<Widget> buttons = new List();
print(widget.number);
for(var i = 0;i < widget.number; i++) {
buttons.add(
SizedBox(
width: 40,
height:40,
child: Padding(
padding: EdgeInsets.all(5.0),
child: FlatButton(
color: tapped == i ? Colors.blue : Colors.red,
textColor: Colors.white,
disabledColor: Colors.grey,
disabledTextColor: Colors.black,
splashColor: Colors.blueAccent,
child: Text("I am button '$i'"),
onPressed: () { setState(() { tapped = i; }); },
),
)
)
);
}
return Row(children: buttons);
}
}
EDIT: You can potentially do better than this by creating your own Button widget like this:
class MyClickedButton extends StatefulWidget {
MyClickedButton({Key key, this.onPressed}) : super(key: key);
// allow the widget that renders this widget to pass
// in a callback for when the button is pressed
final Function() onPressed;
#override
MyClickedButtonState createState() => MyClickedButtonState();
}
class MyClickedButtonState extends State<MyClickedButton> {
bool pressed;
#override
Widget build(BuildContext context) {
return SizedBox(
width: 40,
height:40,
child: Padding(
padding: EdgeInsets.all(5.0),
child: FlatButton(
color: pressed ? Colors.blue : Colors.red,
textColor: Colors.white,
disabledColor: Colors.grey,
disabledTextColor: Colors.black,
splashColor: Colors.blueAccent,
child: Text("I am a button"),
onPressed: () {
setState(() => { pressed = !pressed });
// call the callback that was passed in from the parent widget
widget.onPressed();
},
),
)
);
}
}
No matter what UI framework you are using (angular, vue, flutter, react) I find lifting state up by react extremely useful.
Put state where you need it, and only where you need it.
Generate Random color using
color: Colors.primaries[Random().nextInt(Colors.primaries.length)],