how to disable tooltip dynamcically in flutter? - flutter

I can disable the tooltip statically.
But I want to disable tooltip dynamically when i click flatbutton.But Couldnt disable dynamically and i have no idea to do that.
This is my code:
import 'package:flutter/material.dart';
void main(){
runApp(MaterialApp(home: HelloWorld(),debugShowCheckedModeBanner: false,));
}
class HelloWorld extends StatefulWidget {
#override
_HelloWorldState createState() => _HelloWorldState();
}
class _HelloWorldState extends State<HelloWorld> {
bool check = false;
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(children: <Widget>[
TopToolbar(),
FlatButton(
child: Text("Disable Tooltip"),
onPressed: () {
setState(() {
TopToolbar toolbar = new TopToolbar();
toolbar.showTooltip = false;
});
},
),
]),
),
));
}
}
class TopToolbar extends StatefulWidget {
bool showTooltip;
final Color backgroundColor;
final double height;
bool isVisible;
TopToolbar({
this.height = 55,
this.isVisible = true,
this.backgroundColor = const Color(0xFFEEEEEE),
Key key,this.showTooltip=true,
}) : super(key: key);
#override
_TopToolbarState createState() => _TopToolbarState();
}
class _TopToolbarState extends State<TopToolbar> {
#override
Widget build(BuildContext context) {
if (widget.isVisible) {
return Container(
foregroundDecoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey,
),
),
),
margin: EdgeInsets.only(bottom: 1),
color: widget.backgroundColor,
height: widget.height,
child: Stack(
children: <Widget>[
Positioned(
top: 7,
right: 60,
height: 40,
width: 40,
child: RawMaterialButton(
elevation: 0.0,
fillColor: widget.backgroundColor,
splashColor: Colors.grey[300],
child: IconButton(
icon: Icon(
Icons.bookmark,
color: Colors.grey[500],
size: 25,
),
onPressed: (){},
tooltip: widget.showTooltip ? "Bookmark" : null,
),
onPressed: (){},
),
),
],
),
);
} else {
return Container();
}
}
}
If I give statically false. it works fine.
For example : If add child like TopToolbar(showTooltip : false),it works fine,
But If i give toolbar.showTooltip = false in Flatbutton onPressed method,it doesnt work.
I want to disble it in dynamically. please help me to do that.

we can hide or deactivate tooltip programmatically like below,
Future.delayed(
Duration(seconds: 2),
() {
tooltip?.deactivate();
}
);
Here, we can set time according to your requirement.(Currently, we are set 2 sec.)

import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: HelloWorld(),
debugShowCheckedModeBanner: false,
));
}
class HelloWorld extends StatefulWidget {
#override
_HelloWorldState createState() => _HelloWorldState();
}
class _HelloWorldState extends State<HelloWorld> {
bool check = false;
bool showTooltip = true;
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(children: <Widget>[
TopToolbar(showTooltip: showTooltip),
FlatButton(
child: Text("Disable Tooltip"),
onPressed: () {
setState(() {
showTooltip = false;
});
},
),
]),
),
));
}
}
class TopToolbar extends StatefulWidget {
final bool showTooltip;
final Color backgroundColor;
final double height;
final bool isVisible;
TopToolbar({
this.height = 55,
this.isVisible = true,
this.backgroundColor = const Color(0xFFEEEEEE),
Key key,
this.showTooltip = true,
}) : super(key: key);
#override
_TopToolbarState createState() => _TopToolbarState();
}
class _TopToolbarState extends State<TopToolbar> {
#override
Widget build(BuildContext context) {
if (widget.isVisible) {
return Container(
foregroundDecoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey,
),
),
),
margin: EdgeInsets.only(bottom: 1),
color: widget.backgroundColor,
height: widget.height,
child: Stack(
children: <Widget>[
Positioned(
top: 7,
right: 60,
height: 40,
width: 40,
child: RawMaterialButton(
elevation: 0.0,
fillColor: widget.backgroundColor,
splashColor: Colors.grey[300],
child: IconButton(
icon: Icon(
Icons.bookmark,
color: Colors.grey[500],
size: 25,
),
onPressed: () {},
tooltip: widget.showTooltip ? 'Bookmark' : null,
),
onPressed: () {},
),
),
],
),
);
} else {
return Container();
}
}
}

I've used this method to hide tooltips:
Tooltip(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0),
),
textStyle: TextStyle(color: Colors.white.withOpacity(0)),
message: 'Certificates',
child: Container()
);

Make the property message='' // empty string
setState((){messageText=''});
Tooltip(
message: messageText,
...
)

Related

Consumer doesn't update the UI when using notifyListeners()

I'm using animated containers and I want them to change color when I use NotifyListeners();
Thing is, the color only updates when you click on the container, otherwise it remains the same.
I tried switching to normal containers, I tried changing the home screen to stateful, nothing seems to work, any help is appreciated.
Github link: https://github.com/amrogad/beat_maker
void main() {
runApp(MultiProvider(providers: [
ChangeNotifierProvider<SoundProvider>(create: (_) => SoundProvider(),
),
ChangeNotifierProvider<IconProvider>(create: (_) => IconProvider(),
),
], child: MyApp()));
}
class IconProvider extends ChangeNotifier {
Color primary1 = Colors.deepPurpleAccent;
Color secondary1 = Colors.deepPurple;
Color primary2 = Colors.yellowAccent;
Color secondary2 = Colors.orangeAccent;
Color primary3 = Colors.cyanAccent;
Color secondary3 = Colors.blue;
Color primary4 = Colors.lime;
Color secondary4 = Colors.lightGreen;
void changeIcons(
Color primaryPath1,
Color secondaryPath1,
Color primaryPath2,
Color secondaryPath2,
Color primaryPath3,
Color secondaryPath3,
Color primaryPath4,
Color secondaryPath4,
) {
primary1 = primaryPath1;
secondary1 = secondaryPath1;
primary2 = primaryPath2;
secondary2 = secondaryPath2;
primary3 = primaryPath3;
secondary3 = secondaryPath3;
primary4 = primaryPath4;
secondary4 = secondaryPath4;
notifyListeners();
}
}
class HomeScreen extends StatelessWidget {
static const String routeName = 'Home Screen';
#override
Widget build(BuildContext context) {
var soundProvider = Provider.of<SoundProvider>(context);
return SafeArea(
child: Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.black,
title: Text(
'Beat Maker',
style: GoogleFonts.anton(color: Colors.lime, fontSize: 24),
),
centerTitle: true,
actions: [
GestureDetector(
onTap: () {
Navigator.of(context).pushNamed(SettingsScreen.routeName);
},
child: Icon(
Icons.settings,
color: Colors.lime,
size: 24,
)),
SizedBox(
width: 10,
),
],
),
body: Consumer<IconProvider>(
builder: (context, icon, child) {
return GridView(
physics: NeverScrollableScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4
),
children: [
SoundButton(
icon.primary1, icon.secondary1, soundProvider.note1),
SoundButton(
icon.primary2, icon.secondary2, soundProvider.note2),
SoundButton(
icon.primary3, icon.secondary3, soundProvider.note3),
SoundButton(
icon.primary4, icon.secondary4, soundProvider.note4)
],
);
}
),
),
);
}
class SoundButton extends StatefulWidget {
final Color mainColor;
final Color sideColor;
final note;
const SoundButton(this.mainColor, this.sideColor, this.note, {Key? key})
: super(key: key);
#override
State<SoundButton> createState() => _SoundButtonState();
}
class _SoundButtonState extends State<SoundButton> {
late Color _mainColor;
late Color _sideColor;
final player = AudioPlayer();
#override
void initState() {
_mainColor = widget.mainColor;
_sideColor = widget.sideColor;
super.initState();
}
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
_mainColor = Colors.redAccent;
_sideColor = Colors.red;
player.play(AssetSource(widget.note));
});
},
child: AnimatedContainer(
decoration: BoxDecoration(
border: Border.all(width: 1),
gradient: RadialGradient(colors: [_mainColor, _sideColor]),
boxShadow: const [
BoxShadow(
blurRadius: 1.0,
spreadRadius: 1.0,
offset: Offset(
1.0,
1.0,
),
),
]),
curve: Curves.easeOutCubic,
onEnd: () => Reset(),
duration: const Duration(milliseconds: 100),
),
);
}
void Reset() {
setState(() {
_mainColor = widget.mainColor;
_sideColor = widget.sideColor;
});
}
}
class OpenIconBottomSheet extends StatelessWidget {
const OpenIconBottomSheet({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
var iconProvider = Provider.of<IconProvider>(context);
return Container(
height: 106,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12), topRight: Radius.circular(12)),
color: Colors.black,
border: Border.all(width: 3, color: Colors.lime)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
InkWell(
onTap: () {
iconProvider.changeIcons(
Colors.deepPurpleAccent,
Colors.deepPurple,
Colors.yellowAccent,
Colors.orangeAccent,
Colors.cyanAccent,
Colors.blue,
Colors.lime,
Colors.lightGreen,
);
Navigator.pop(context);
},
child: isSelected(
'Main Theme',
iconProvider.primary1 == Colors.deepPurpleAccent
? true
: false)),
Container(
width: double.infinity,
height: 3,
color: Colors.lime,
),
SizedBox(
height: 7,
),
InkWell(
onTap: () {
iconProvider.changeIcons(
Colors.white70,
Colors.white,
Colors.pinkAccent,
Colors.pink,
Colors.tealAccent,
Colors.teal,
Colors.amberAccent,
Colors.redAccent,
);
Navigator.pop(context);
},
child: isSelected('Secondary Theme',
iconProvider.primary1 == Colors.white70 ? true : false)),
],
),
);
}
Widget isSelected(String text, bool selected) {
if (selected) {
return Padding(
padding: EdgeInsets.all(6),
child: Text(text,
style: GoogleFonts.anton(color: Colors.lime, fontSize: 24)),
);
} else {
return Padding(
padding: EdgeInsets.all(6),
child: Text(text,
style: GoogleFonts.anton(color: Colors.white, fontSize: 24)),
);
}
}
}

Dart Function not inputting Variables

I'm creating a Dart Function to use repeatedly across my app. its 2 buttons linked to a counter locally (localCounter, it's between the 2 buttons) as well as linked to a counter that catches all the button presses across the app (GlobalCuonter) when I input the the integers directly into the code, it works fine but when I use the it as a function, and make it so i can input the variables, it doesn't seem to work but i'm also not getting any errors in the code.
import 'package:flutter/material.dart';
void main() {
runApp(
const MyApp(),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.black,
body: SafeArea(
child: MainPage(),
),
),
);
}
}
class MainPage extends StatefulWidget {
const MainPage({Key? key}) : super(key: key);
#override
State<MainPage> createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
int TP1LeftCounter = 0; //localCounter
int movpLeftCounter = 0; //globalCounter
Row TpScores(int localCounter, int globalCounter) { //Dart Function I'm trying to create
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: InkWell(
onTap: () {
setState(() {
if (localCounter > 0) localCounter--;
if (globalCounter > 0) globalCounter--;
});
},
child: Container(
child: Icon(Icons.remove, color: Colors.white),
width: 25.0,
height: 35.0,
color: Colors.blueGrey[900],
),
),
),
Container(
child: Text(
'$localCounter',
style: TextStyle(
fontFamily: 'SourceSansPro',
fontSize: 40.0,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: InkWell(
onTap: () {
setState(() {
if (localCounter < 12) localCounter++;
if (globalCounter < 12) globalCounter++;
});
},
child: Container(
child: Icon(Icons.add, color: Colors.white),
width: 25.0,
height: 35.0,
color: Colors.blueGrey[900],
),
),
),
],
);
}
A
nd then in my build i put:
Expanded(
child: Container(
height: 50.0,
child: TpScores(TP1LeftCounter, movpLeftCounter),
),
),
the counters don't tick up or down but the buttons are working.
am I missing something? cheers
It's because the value is copied, you're not incrementing TP1LeftCounter and movpLeftCounter but localCounter and globalCounter
You should increment TP1LeftCounter, movpLeftCounter in the setState method.
Example
void main() {
var v1 = 0;
void incr(int value) {
value++;
print('value is $value');
print('v1 is $v1');
}
incr(v1);
}
Will output
value is 1
v1 is 0

Get all the scores from all widgets

I am building a quiz app and I created a custom widget to save me a lot of time as I have a lot of questions for the quiz. Everything works apart from the scoring system. If I create multiple instances of the same widget the score will not be incremented and it will stay on 1. Is there any way I can pass each score of the widgets to a global variable in my main widget so then I can add all the scores? (I'm new to flutter).
Custom Widget
class Questions extends StatefulWidget {
final String imagePath;
final String question;
final String answer1;
final String answer2;
final String answer3;
final String answer4;
final bool iscorrectAnswer1;
final bool iscorrectAnswer2;
final bool iscorrectAnswer3;
final bool iscorrectAnswer4;
int score = 0;
bool questionsAnswered = false;
Questions(
this.imagePath,
this.question,
this.answer1,
this.answer2,
this.answer3,
this.answer4,
this.iscorrectAnswer1,
this.iscorrectAnswer2,
this.iscorrectAnswer3,
this.iscorrectAnswer4,
);
#override
_QuestionsState createState() => _QuestionsState();
}
class _QuestionsState extends State<Questions> {
disableButton() {
setState(() {
widget.questionsAnswered = true;
Quiz().score += widget.score;
});
}
#override
#override
Widget build(BuildContext context) {
return Column(
children: [
SizedBox(
width: 600,
height: 600,
child: Image.asset(widget.imagePath),
),
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: EdgeInsets.only(
top: 20,
),
child: Text(
widget.question,
style: TextStyle(
color: Colors.white,
fontSize: 38,
),
),
)),
Padding(
padding: EdgeInsets.only(
top: 40,
),
child: SizedBox(
width: 500,
height: 60,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(15)),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Color(0xFF304e60),
),
),
child: Text(
widget.answer1,
style: TextStyle(
color: Colors.white,
fontSize: 15,
),
),
onPressed: widget.questionsAnswered == false
? () {
setState(() {
if (widget.iscorrectAnswer1 == true) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Correct!'),
),
);
disableButton();
widget.score += 1;
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(
content: Text('Wrong Answer!'),
));
}
});
print(widget.iscorrectAnswer1);
print(widget.score);
}
: null),
),
)),
Padding(
padding: EdgeInsets.only(
top: 10,
),
child: SizedBox(
width: 500,
height: 60,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(15)),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Color(0xFF565462))),
child: Text(
widget.answer2,
style: TextStyle(
color: Colors.white,
fontSize: 15,
),
),
onPressed: widget.questionsAnswered == false
? () {
setState(() {
if (widget.iscorrectAnswer2 == true) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Correct!'),
),
);
widget.score += 1;
} else {
disableButton();
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(
content: Text('Wrong Answer!'),
));
}
});
}
: null),
),
)),
Padding(
padding: EdgeInsets.only(
top: 10,
),
child: SizedBox(
width: 500,
height: 60,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(15)),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Color(0xFF84693b))),
child: Text(
widget.answer3,
style: TextStyle(
color: Colors.white,
fontSize: 15,
),
),
onPressed: widget.questionsAnswered == false
? () {
setState(() {
if (widget.iscorrectAnswer3 == true) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Correct!'),
),
);
widget.score += 1;
} else {
disableButton();
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(
content: Text('Wrong Answer!'),
));
}
});
}
: null),
),
),
)
],
);
}
}
Main widget where I call this custom widget
class Quiz extends StatefulWidget {
Quiz({Key? key}) : super(key: key);
int score = 0;
#override
_QuizState createState() => _QuizState();
}
class _QuizState extends State<Quiz> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('CyberQuiz'),
),
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Column(
children: [
Questions(
'images/malware_quiz.jpeg',
'1. What is a malware?',
'Designed to damage computers, servers or any other devices',
"Used to get user's credentials",
"It's used to destroy networks",
'',
true,
false,
false,
false,
),
],
)));
}
}
As you suggest in your question, you could create a global variable and increment/decrease/reset that.
Basic example code:
import 'package:flutter/material.dart';
class Score {
static int score = 0;
}
class ScoreCounter extends StatefulWidget {
const ScoreCounter({Key? key}) : super(key: key);
#override
State<ScoreCounter> createState() => _ScoreCounterState();
}
class _ScoreCounterState extends State<ScoreCounter> {
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: ElevatedButton(
onPressed: () {
setState(() {
Score.score++;
});
},
child: Text('increase score'),
),
),
Expanded(child: Text(Score.score.toString()))
],
);
}
}
Another option is to use the Provider package - link here which has an example
Provider Package

How to disable the tooltip dynamically in flutter? [duplicate]

This question already has answers here:
how to disable tooltip dynamcically in flutter?
(4 answers)
Closed 2 years ago.
I can disable the tooltip statically.
But I want to disable tooltip dynamically when i click flatbutton.But Couldnt disable dynamically and i have no idea to do that.
If I give statically false. it works fine.
For example : If add child like TopToolbar(showTooltip : false),it works fine,
But If i give toolbar.showTooltip = false in Flatbutton onPressed method,it doesnt work.
I want to disble it in dynamically. please help me to do that.
This is my code:
import 'package:flutter/material.dart';
void main(){
runApp(MaterialApp(home: HelloWorld(),debugShowCheckedModeBanner: false,));
}
class HelloWorld extends StatefulWidget {
#override
_HelloWorldState createState() => _HelloWorldState();
}
class _HelloWorldState extends State<HelloWorld> {
bool check = false;
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(children: <Widget>[
TopToolbar(),
FlatButton(
child: Text("Disable Tooltip"),
onPressed: () {
setState(() {
TopToolbar toolbar = new TopToolbar();
toolbar.showTooltip = false;
});
},
),
]),
),
));
}
}
class TopToolbar extends StatefulWidget {
bool showTooltip;
final Color backgroundColor;
final double height;
bool isVisible;
TopToolbar({
this.height = 55,
this.isVisible = true,
this.backgroundColor = const Color(0xFFEEEEEE),
Key key,this.showTooltip=true,
}) : super(key: key);
#override
_TopToolbarState createState() => _TopToolbarState();
}
class _TopToolbarState extends State<TopToolbar> {
#override
Widget build(BuildContext context) {
if (widget.isVisible) {
return Container(
foregroundDecoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey,
),
),
),
margin: EdgeInsets.only(bottom: 1),
color: widget.backgroundColor,
height: widget.height,
child: Stack(
children: <Widget>[
Positioned(
top: 7,
right: 60,
height: 40,
width: 40,
child: RawMaterialButton(
elevation: 0.0,
fillColor: widget.backgroundColor,
splashColor: Colors.grey[300],
child: IconButton(
icon: Icon(
Icons.bookmark,
color: Colors.grey[500],
size: 25,
),
onPressed: (){},
tooltip: widget.showTooltip ? "Bookmark" : null,
),
onPressed: (){},
),
),
],
),
);
} else {
return Container();
}
}
}
You have to store whether to show the tooltip in _HelloWorldState, not in the TopToolbar.
This would lead to doing something like this in _HelloWorldState:
class _HelloWorldState extends State<HelloWorld> {
bool showTip = true;
bool check = false;
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(children: <Widget>[
TopToolbar(showTip),
FlatButton(
child: Text("Disable Tooltip"),
onPressed: () {
setState(() {
showTip = false;
});
},
),
]),
),
));
}
}
showTooltip should also be marked as final in TopToolbar class.
Your current implementation creates a new TopToolbar widget, it doesn't modify the existing widget. TopToolbar toolbar = new TopToolbar(); creates a completely different widget, just one that isn't ever mounted and shown. Therefore, toolbar.showTooltip = false; has no visible effect.
Alternatively to what I have shown you can access of the State of the TopToolbar using a GlobalKey, but I wouldn't recommend this for a beginner, it isn't necessary for your implementation at the moment, and GlobalKeys are relatively expensive.
This is too simple buddy,
make 1 global variable below main method
bool isTooltipActive = true;
Now change onPressed method like this
FlatButton(
child: Text("Disable Tooltip"),
onPressed: () {
setState(() {
if(isToolTipAvtive == false){
isToolTipAvtive = true;
}else{
isToolTipAvtive = false;
}
});
},
),
And change bookmark tooltip line like this
tooltip: isToolTipAvtive ? "Bookmark" : null,

how i can make custom switch button in flutter? [duplicate]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
In my application, I want the switch is used to toggle a setting between on/off which is true/false respectively. When I went to build it, it turned out that Flutter provides a default switch, but it is not what I want. I want to customize it accordingly to my UI.
This is the Flutter switch button:
Here is what I want:
How can I make it possible for my UI?
Set
bool _switchValue = true;
in your screen.dart file:
CupertinoSwitch(
value: _switchValue,
onChanged: (value) {
setState(() {
_switchValue = value;
});
},
),
You can use package https://pub.dev/packages/custom_switch or fork it and modify it to your needs.
Full code
import 'package:custom_switch/custom_switch.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.deepOrange
),
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
bool status = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Custom Switch Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CustomSwitch(
activeColor: Colors.pinkAccent,
value: status,
onChanged: (value) {
print("VALUE : $value");
setState(() {
status = value;
});
},
),
SizedBox(height: 12.0,),
Text('Value : $status', style: TextStyle(
color: Colors.black,
fontSize: 20.0
),)
],
),
),
);
}
}
Create a custom switch class
class CustomSwitch extends StatefulWidget {
final bool value;
final ValueChanged<bool> onChanged;
CustomSwitch({Key? key, required this.value, required this.onChanged})
: super(key: key);
#override
_CustomSwitchState createState() => _CustomSwitchState();
}
class _CustomSwitchState extends State<CustomSwitch>
with SingleTickerProviderStateMixin {
Animation? _circleAnimation;
AnimationController? _animationController;
#override
void initState() {
super.initState();
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 60));
_circleAnimation = AlignmentTween(
begin: widget.value ? Alignment.centerRight : Alignment.centerLeft,
end: widget.value ? Alignment.centerLeft : Alignment.centerRight)
.animate(CurvedAnimation(
parent: _animationController!, curve: Curves.linear));
}
#override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: _animationController!,
builder: (context, child) {
return GestureDetector(
onTap: () {
if (_animationController!.isCompleted) {
_animationController!.reverse();
} else {
_animationController!.forward();
}
widget.value == false
? widget.onChanged(true)
: widget.onChanged(false);
},
child: Container(
width: 45.0,
height: 28.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.0),
color: _circleAnimation!.value == Alignment.centerLeft
? Colors.grey
: Colors.blue,
),
child: Padding(
padding: const EdgeInsets.only(
top: 2.0, bottom: 2.0, right: 2.0, left: 2.0),
child: Container(
alignment:
widget.value ? ((Directionality.of(context) == TextDirection.rtl) ? Alignment.centerRight : Alignment.centerLeft ) : ((Directionality.of(context) == TextDirection.rtl) ? Alignment.centerLeft : Alignment.centerRight),
child: Container(
width: 20.0,
height: 20.0,
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.white),
),
),
),
),
);
},
);
}
}
Call this class as widget and use the value parameter to set the state of the switch
bool _enable = false;
CustomSwitch(
value: _enable,
onChanged: (bool val){
setState(() {
_enable = val;
});
},
),
For a custom switch, I used this package:
https://pub.dev/packages/flutter_switch
You can customize the height and width of the switch, the border radius of the switch, the colors, the toggle size, etc.
Install:
dependencies:
flutter_switch: ^0.0.2
Import:
import 'package:flutter_switch/flutter_switch.dart';
Sample Usage:
FlutterSwitch(
height: 20.0,
width: 40.0,
padding: 4.0,
toggleSize: 15.0,
borderRadius: 10.0,
activeColor: lets_cyan,
value: isToggled,
onToggle: (value) {
setState(() {
isToggled = value;
});
},
),
You can achieve such a design using this package:
This usage is from their README file:
import 'package:custom_switch_button/custom_switch_button.dart';
bool isChecked = false;
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Custom Switch Button example app'),
),
body: GestureDetector(
onTap: () {
setState(() {
isChecked = !isChecked;
});
},
child: Center(
child: CustomSwitchButton(
backgroundColor: Colors.blueGrey,
unCheckedColor: Colors.white,
animationDuration: Duration(milliseconds: 400),
checkedColor: Colors.lightGreen,
checked: isChecked,
),
),
),
),
);
Final result: