Reusable Switch Widget using the flutter_switch package - flutter

I am trying to make a reusable Switch Widget using the flutter_switch package https://pub.dev/packages/flutter_switch.
Unfortnaly how i maked it, it does not change the look, the size etc. of the widget when i use it.
If i make a reusable Swich without using the package it works fine.
Somebody have a idea what is wrong here?
Thanks for any help
import 'package:flutter/material.dart';
import 'package:flutter_switch/flutter_switch.dart';
class MyFlutterSwitch extends StatelessWidget {
const MyFlutterSwitch(
{required this.onToggle,
required this.value,
required this.activeColor,
required this.inactiveColor,
required this.activeTextColor,
required this.inactiveTextColor,
required this.toggleColor,
required this.activeToggleColor,
required this.inactiveToggleColor,
this.padding,
this.borderRadius,
this.toogleSize,
Key? key})
: super(key: key);
final void Function(bool) onToggle;
final bool value;
final Color activeColor;
final Color inactiveColor;
final Color activeTextColor;
final Color inactiveTextColor;
final Color toggleColor;
final Color? activeToggleColor;
final Color? inactiveToggleColor;
final double? padding;
final double? borderRadius;
final double? toogleSize;
#override
Widget build(BuildContext context) {
return SizedBox(
height: 20.0,
width: 40.0,
child: FlutterSwitch(
toggleSize: 15.0,
borderRadius: 60.0,
padding: 3.0,
activeTextColor: const Color.fromARGB(255, 198, 40, 40),
inactiveTextColor: const Color.fromARGB(255, 46, 125, 50),
activeToggleColor: Colors.red[800],
inactiveToggleColor: Colors.green[800],
inactiveColor: const Color(0xFF55DDCA),
activeColor: const Color(0xFFF87A54),
onToggle: onToggle,
value: value,
),
);
}
}

You need to pass your functions values if you want to pass custom values in every instance of this widget if you want :
class MyFlutterSwitch extends StatelessWidget {
const MyFlutterSwitch(
{
this.toggleSize: 15.0,
this.borderRadius: 60.0,
this.padding: 3.0,
this.activeTextColor: const Color.fromARGB(255, 198, 40, 40),
this.inactiveTextColor: const Color.fromARGB(255, 46, 125, 50),
this.activeToggleColor: Colors.red[800],
this.inactiveToggleColor: Colors.green[800],
this.inactiveColor: const Color(0xFF55DDCA),
this.activeColor: const Color(0xFFF87A54),
required this.onToggle,
required this.value,
Key? key})
: super(key: key);
final void Function(bool) onToggle;
final bool value;
final Color activeColor;
final Color inactiveColor;
final Color activeTextColor;
final Color inactiveTextColor;
final Color toggleColor;
final Color? activeToggleColor;
final Color? inactiveToggleColor;
final double? padding;
final double? borderRadius;
final double? toogleSize;
#override
Widget build(BuildContext context) {
return SizedBox(
height: 20.0,
width: 40.0,
child: FlutterSwitch(
toggleSize: toggleSize,
borderRadius: borderRadius,
padding: padding,
activeTextColor: activeTextColor,
inactiveTextColor: inactiveTextColor,
activeToggleColor: activeToggleColor,
inactiveToggleColor: inactiveToggleColor,
inactiveColor: inactiveColor,
activeColor: activeColor,
onToggle: onToggle,
value: value,
),
);
}
}

It looks like you're not passing in the values from your parameter list. Your build method should look something like this.
#override
Widget build(BuildContext context) {
return SizedBox(
height: 20.0,
width: 40.0,
child: FlutterSwitch(
toggleSize: toogleSize ?? 15.0,
borderRadius: borderRadius ?? 60.0,
padding: padding ?? 3.0,
activeTextColor: activeColor,
inactiveTextColor: inactiveColor,
activeToggleColor: activeToggleColor ?? Colors.red[800],
inactiveToggleColor: inactiveToggleColor ?? Colors.green[800],
inactiveColor: inactiveColor,
activeColor: activeColor,
onToggle: onToggle,
value: value,
),
);
}

Related

Flutter Button Click and Button Color Control

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,
),
)

Is it possible to trigger a CupertinoContextMenu from a single click on an icon in flutter?

I have the CupertinoContextMenu setup and it works well. However, I have an Icon in a separate widget which when tapped (single tap) would also trigger the opening of the Context Menu.
Is anything like this possible?
I hacked something a little remotly iosy together from the material PopupMenuButton. Maybe it can help you as a basis for styling.
import 'package:flutter/material.dart';
class IosLikePopupMenuButton extends StatelessWidget {
final double borderRadius;
final Color _backgroundColor = const Color.fromARGB(209, 235, 235, 235);
final List<IosLikePopupMenuItem> Function(BuildContext) itemBuilder;
const IosLikePopupMenuButton({
Key? key,
this.borderRadius = 24.0,
required this.itemBuilder,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return PopupMenuButton<String>(
icon: const Icon(Icons.more_horiz),
itemBuilder: (context1) {
/// give the current context and map the IosLikePopupMenuItem dtos to PopupMenuEntry while splicing in dividers
return itemBuilder(context1)
.map((e) => e.popupMenuItems())
.toList()
.fold(
List<PopupMenuEntry<String>>.empty(growable: true),
(p, e) => [
...p,
...[e, const PopupMenuDivider()]
])
/// delete the last divider
..removeLast();
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(borderRadius),
),
),
color: _backgroundColor,
);
}
}
class IosLikePopupMenuItem {
final double menuItemHeight, minSpaceBtwnTxtAndIcon;
final String lableText;
final IconData icon;
final void Function() onTap;
final TextStyle _textStyle =
const TextStyle(color: Colors.black, fontSize: 22.0);
IosLikePopupMenuItem({
this.menuItemHeight = 24.0,
this.minSpaceBtwnTxtAndIcon = 48.0,
required this.lableText,
required this.icon,
required this.onTap,
});
PopupMenuItem<String> popupMenuItems() => PopupMenuItem<String>(
height: menuItemHeight,
textStyle: _textStyle,
onTap: onTap,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
lableText,
),
SizedBox(width: minSpaceBtwnTxtAndIcon),
Icon(icon),
],
),
);
}

4 positional argument(s) expected, but 0 found

Not able to print clicked after clicking and all area from CustomBtn bracket is red underlined till the bracket closed
CustomBtn(
text: "Create New Account",
onPressed: () {
print("Clicked");
},
),
Here is CustomBtn class it is another file
import 'package:flutter/material.dart';
class CustomBtn extends StatelessWidget {
final String write;
final void Function() onPressed;
final bool outlineBtn;
final bool isLoading;
CustomBtn(this.write, this.onPressed, this.outlineBtn, this.isLoading, {Key? key} : super(key: key));
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPressed,
child: Container(
height: 70.0,
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border.all(
color: Colors.black,
width: 2.0,
),
borderRadius: BorderRadius.circular(
12.0,
),
),
margin: const EdgeInsets.symmetric(
horizontal: 24.0,
vertical: 24.0,
),
child: Text(
write ?? "text",
style: const TextStyle(
fontSize: 16.0,
color: Colors.black,
fontWeight: FontWeight.w600,
),
),
),
);
}
}
I am Trying and seeing from this youtube video
https://youtu.be/YPqYnM6KjZI
and here is the time where i am facing problem
at 12:50 https://youtu.be/YPqYnM6KjZI?t=770[][2]
your constructor has positional parameters and therefore are required and you have to pass values to it otherwise the compiler complains :). Either change them to named parameters and make the type nullable like so:
final String? write;
CustomBtn({
this.write,
etc...
})
or simply pass some values
This is because your constructor has
final String write;
final void Function() onPressed;
final bool outlineBtn;
final bool isLoading;
so it requires to send the parameters to works.
Here you Flutter is waiting a call of your customBtn like this :
CustomBtn(
write: "Create New Account",
onPressed: () {
print("Clicked");
},
outlineBtn: false,
isLoading: false,
),
If you don't need to require this parameters, you can put a ? after the type in the declaration, like below.
final String? write;
final void? Function() onPressed;
final bool? outlineBtn;
final bool? isLoading;
Just convert this line:
CustomBtn(this.write, this.onPressed, this.outlineBtn, this.isLoading, {Key? key} : super(key: key));
to:
CustomBtn({this.write, this.onPressed, this.outlineBtn, this.isLoading, Key? key} : super(key: key));

How to display a text or an IconButton in a container child?

I'm having this widget that wants to use in a different part of the app but the problem is sometimes the child is Text and sometimes is IconButton How should I change the child: Using ternary operator on the child of the widget ? ?
class MiddleBox extends StatelessWidget {
final double widthBox;
final double heightBox;
final IconData icon;
final String textof;
final Function onpressed;
const MiddleBox(
{Key key,
#required this.widthBox,
#required this.heightBox,
this.icon,
this.textof,
this.onpressed})
: super(key: key);
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(13),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
width: widthBox,
height: heightBox,
child: IconButton(
icon: Center(
child: Icon(
icon,
),
),
onPressed: onpressed,
),
);
}
}
I believe you are using this widget in some other file. If there are multiple options that you would like to have in place of IconButton, try below code:
class MiddleBox extends StatelessWidget {
final double widthBox;
final double heightBox;
final Widget child;
final Function onpressed;
const MiddleBox(
{Key key,
#required this.widthBox,
#required this.heightBox,
this.icon,
this.textof,
this.onpressed})
: super(key: key);
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(13),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
width: widthBox,
height: heightBox,
child: child,
);
}
}
In case you want to have either IconButton or Text, try below code:
class MiddleBox extends StatelessWidget {
final double widthBox;
final double heightBox;
final IconData icon;
final String textof;
final Function onpressed;
const MiddleBox(
{Key key,
#required this.widthBox,
#required this.heightBox,
this.icon,
this.textof,
this.onpressed})
: super(key: key);
#override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(13),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.2),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 3), // changes position of shadow
),
],
),
width: widthBox,
height: heightBox,
child: textof == null || textof == ''
? IconButton(
icon: Center(
child: Icon(
icon,
),
),
onPressed: onpressed,
)
: textof,
);
}
}
What I did was i used the Iternary operator based on the Width of the Container. becacuase if the container is bigger than 80 it has text otherwise it has Icon.

Flutter RawMaterialButton won't get transparent

I'm using this simple CircularButtonWithIcon. The one problem is that it won't respect transparency when no color is setted.
class CircularButtonWithIcon extends StatefulWidget {
CircularButtonWithIcon({
Key key,
#required this.onPress,
this.padding,
this.border,
this.active = false,
this.marginRight,
this.marginLeft,
this.icon,
this.color,
this.activeColor,
this.text,
this.splashColor,
this.image,
this.hasState,
this.borderColor,
}) : super(key: key);
final double padding;
final double border;
final double marginRight;
final double marginLeft;
final Icon icon;
final Image image;
final Color color;
final Color activeColor;
final Color borderColor;
final Widget text;
final Color splashColor;
final Function onPress;
final bool active;
final bool hasState;
#override
_CircularButtonWithIconState createState() => _CircularButtonWithIconState();
}
class _CircularButtonWithIconState extends State<CircularButtonWithIcon> {
bool active;
#override
void initState() {
super.initState();
active = widget.active;
}
#override
Widget build(BuildContext context) {
return FittedBox(
child: Container(
margin: EdgeInsets.only(left: widget.marginLeft ?? 0, right: widget.marginRight ?? 0),
child: RawMaterialButton(
onPressed: () {
setState(() {
active = !active; // don't use widget.active
});
if (widget.onPress != null) widget.onPress();
},
fillColor: active
? widget.activeColor ?? widget.color ?? Colors.transparent
: widget.color ?? Colors.transparent,
splashColor: widget.splashColor ?? Colors.grey,
child: widget.text != null
? Container(
child: widget.text,
)
: widget.image ?? widget.icon,
//padding: EdgeInsets.all(15.0),
padding: widget.padding != null ? EdgeInsets.all(widget.padding) : EdgeInsets.all(15.0),
shape: CircleBorder(
side: BorderSide(
width: widget.border ?? 2.0,
style: BorderStyle.solid,
color: widget.borderColor ?? Colors.grey),
),
),
),
);
}
}
Take a look at:
fillColor: active
? widget.activeColor ?? widget.color ?? Colors.transparent
: widget.color ?? Colors.transparent,
When no color is seted, it should be transparent.
I did this:
CircularButtonWithIcon(
padding: 10,
border: 3,
onPress: () => {},
icon: Icon(Icons.remove,
color: Color.green,
size: 60))
and it's getting a color background instead of merging:
however it looks like it's just the background but darker. Is it possible that the button is adding a shadow on top of the background color? How can I remove it? I looked at https://api.flutter.dev/flutter/material/RawMaterialButton-class.html and couldn't find anything related to shadow effects on the button