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

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,

Related

Flutter onPressed trigger State of another widget

I need help with flutter build management. My Goal is to rebuild my side navigation bar with the SmallSideMenu() or the opposite SideMenu().
Do you have an idea how I can trigger the Build process of my LargeView widget, so that it's rebuilt with the correspondent SideMenu?
The button is defined like this:
IconButton(
onPressed: () {
checkState();
},
icon: HeroIcon(
HeroIcons.arrowNarrowRight,
size: 16.0,
),
),
The value of the sideMenuOpen variable and function is set globally;
checkState() {
if (sideMenuOpen == true) {
sideMenuOpen = false;
} else {
sideMenuOpen = true;
}
}
the SideMenu is defined here.
class LargeView extends StatefulWidget {
const LargeView({
Key? key,
}) : super(key: key);
#override
State<LargeView> createState() => _LargeViewState();
}
class _LargeViewState extends State<LargeView> {
#override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
child: SizedBox(
width: 100,
child: sideMenuOpen ? SideMenu() : SmallSideMenu(),
),
),
Expanded(
flex: 10,
child: Container(
width: double.infinity,
padding: const EdgeInsets.all(20.0),
color: greyColor,
child: Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15.0)),
child: localNavigator())),
),
)
],
);
}
}
make sideMenuOpen a state in stateful widget and use setState as
checkState() {
if (sideMenuOpen == true) {
setState((){
sideMenuOpen = false;
});
} else {
setState((){
sideMenuOpen = true;
});
}
}
if you want to keep state (open/close) of navigation bar globally for that use some state management like provider instead of using global function.
You can use ValueNotifier instead of single bool. And to update UI it can be used on ValueListenableBuilder.
final ValueNotifier<bool> sideMenuOpen = ValueNotifier(false);
And
child: SizedBox(
width: 100,
child: ValueListenableBuilder<bool>(
valueListenable: sideMenuOpen,
builder: (context, value, child) => value
? SideMenu(),
: SmallSideMenu(),
),
),
And change value like
sideMenuOpen.value = true;

Why is my star system isnt work in flutter

This is my code for making the star turn yellow and grey consistently, but it didn't work. Why?
Widget placeButton(BuildContext context, String name, String image, String id) {
var color;
var isClicked = true;
return Column(children: [
Padding(
padding: const EdgeInsets.fromLTRB(130.0, 0.0, 130.00, 0.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: SizedBox(
height: 300,
width: 400,
child: GestureDetector(
onTap: () {
Navigator.pushNamed(context, id);
},
child: Card(
child: ListTile(
title: Padding(
padding: const EdgeInsets.fromLTRB(20, 5, 20, 0),
child: Text(AppLocalizations.of(context)!.translate(name),
style: TextStyle(fontFamily: 'Manrope', fontSize: 18)),
),
subtitle: Image.network(
image,
height: 250,
),
),
),
),
),
),
),
Container(
height: 40,
width: 200,
padding: EdgeInsets.only(top: 0),
color: Colors.white,
child: ListTile(
leading: Text(
"Rating:",
style: TextStyle(fontFamily: 'Klasik'),
),
trailing: IconButton(
splashRadius: 20,
icon: Icon(Icons.star_border_outlined, color: color),
onPressed: () {
if (isClicked) {
color = Colors.grey;
isClicked = !isClicked;
} else {
color = Colors.yellow;
isClicked = !isClicked;
}
},
),
),
),
]);
}
P/S: Feel free to ask me about the code below. I tried setState but it didn't work. It returns error like this:
The function 'setState' isn't defined.
Try importing the library that defines 'setState', correcting the name to the name of an existing function, or defining a function named 'setState'.
setState is only available within the scope of a StatefulWidget. You might want change the StatelessWidget to a stateful one. Once that's done, you'll need to introduce the variables color and isClicked outside of the build method or any other method that's called from build (such as placeButton in this example). Then you can call setState and change those values.
Here's a simplified example
class MyWidget extends StatefulWidget {
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
// Define these outside of your build method
Color color = Colors.grey;
bool isClicked = false;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: placeButton(context, 'name', 'image', 'id')),
);
}
Widget placeButton(
BuildContext context,
String name,
String image,
String id,
) {
// rest of your function...
onPressed: () {
// Use setState to change the values
setState(() {
if (isClicked) {
color = Colors.grey;
isClicked = !isClicked;
} else {
color = Colors.yellow;
isClicked = !isClicked;
}
});
},
}
}
When using setState, Flutter will run the build function again and notice the values of color and isClicked have changed and use those new values to update the UI.

quantity increase decrease display counter field

New to flutter and tried several solutions I cannot get working for simple item counter
Example icons on row. 0 should increase decrease as i press icon +1 or -1
Donut +1 0 -1
When I press plus_one icon button +1 it updates the print terminal so I know button is working. if I hot refresh the phone emulator the counter and display icon on phone updates to correct count.
How do I tell TextBox to update state ( show updated count on screen) when counter has been increased by OnPress in IconBoxState?
'''
class _IconBoxState extends State<StatefulWidget> {
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Material(
color: Colors.white,
child: Center(
child: Ink(
decoration: const ShapeDecoration(
color: Colors.lightBlue,
shape: CircleBorder(),
),
child: IconButton(
icon: Icon(Icons.plus_one),
color: Colors.white,
iconSize: 25,
onPressed: () {
setState(() {
_counter += 10;
print('this is counter + $_counter');
//new TextBox(); not working....
});
},
),
),
),
),
],
);
}
}
class TextBox extends StatefulWidget {
#override
_TextBoxState createState() => _TextBoxState();
}
class _TextBoxState extends State<TextBox> {
// int _counter = 6;
#override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
width: 50,
height: 50,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(),
),
);
}
}
'''
when you are setting the state with setState it only rebuilds the widget, where it is located and other widget's that the container widget contains, so in your case you have TextBox outside the IconBox, so only IconBox is rebuilt and TextBox can't detect state change so it stays same, you have many ways to solve it. 1. somehow store both of the widget inside the container widget and rebuild the state of the container widget, you can do this, 2. use provider, 3. use InheritedWidget 4. use BloC
This is a full code of version one, so you can play around, You will need to include ContainerWidget inside the page you want it to be displayed or in the Scaffold of MaterialApp:
class ContainerWidget extends StatefulWidget {
#override
_ContainerWidgetState createState() => _ContainerWidgetState();
}
class _ContainerWidgetState extends State<ContainerWidget> {
int counter = 0;
void increase() {
counter += 1;
}
void decrease() {
counter -= 1;
}
#override
void setState(fn) {
super.setState(fn);
}
stateSetter(String event) {
if (event == "increase") {
increase();
setState(() {});
} else if (event == "decrease") {
decrease();
setState(() {});
}
}
#override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
TextBox(
counter: counter,
),
IconBox(
containerSetState: stateSetter,
),
],
),
);
}
}
class IconBox extends StatefulWidget {
final Function containerSetState;
IconBox({this.containerSetState});
#override
_IconBoxState createState() => _IconBoxState();
}
class _IconBoxState extends State<IconBox> {
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Material(
color: Colors.white,
child: Center(
child: Ink(
decoration: const ShapeDecoration(
color: Colors.lightBlue,
shape: CircleBorder(),
),
child: IconButton(
icon: Icon(Icons.plus_one),
color: Colors.white,
iconSize: 25,
onPressed: () {
setState(() {
widget.containerSetState("increase");
//new TextBox(); not working....
});
},
),
),
),
),
Material(
color: Colors.white,
child: Center(
child: Ink(
decoration: const ShapeDecoration(
color: Colors.lightBlue,
shape: CircleBorder(),
),
child: IconButton(
icon: Icon(Icons.exposure_minus_1),
color: Colors.white,
iconSize: 25,
onPressed: () {
setState(() {
widget.containerSetState("decrease");
//new TextBox(); not working....
});
},
),
),
),
),
],
);
}
}
class TextBox extends StatefulWidget {
final int counter;
TextBox({this.counter});
#override
_TextBoxState createState() => _TextBoxState();
}

how to disable tooltip dynamcically in 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,
...
)

How can I pass a custom widget into another custom widget in flutter?

I am trying to pass a custom made container (with background color, title, and onPressed properties) into another custom widget that creates a row of three of these containers. The goal is to be able to input titles for each of these buttons in the second widget like so, TriButton(title1, title2, title3). Any tips or tricks would be appreciated!
Custom container
class RectButton extends StatelessWidget {
RectButton({this.buttonChild, this.bgColor, this.onPress});
final Widget buttonChild;
final Color bgColor;
final Function onPress;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onPress,
child: Container(
constraints: BoxConstraints.expand(width: 100, height: 50),
child: Center(child: buttonChild),
decoration: BoxDecoration(
color: bgColor,
shape: BoxShape.rectangle,
border: Border.all(width: 1, color: Colors.white)),
padding: EdgeInsets.fromLTRB(12, 12, 12, 12),
),
);
}
}
`Tri-button code`
enum Weight {
ideal,
actual,
adjusted,
}
class TriButton extends StatefulWidget {
TriButton({this.title1, this.title2, this.title3, this.buttonChild});
final Text title1;
final Text title2;
final Text title3;
final RectButton buttonChild;
#override
_TriButtonState createState() => _TriButtonState();
}
class _TriButtonState extends State<TriButton> {
Weight selectedWeight;
#override
Widget build(BuildContext context) {
return Center(
child: Container(
constraints: BoxConstraints(maxWidth: 300),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: RectButton(
buttonChild: GOAL TO ENTER TITLE HERE,
onPress: () {
setState(() {
selectedWeight = Weight.adjusted;
});
},
bgColor: selectedWeight == Weight.adjusted
? Colors.orange[600]
: Colors.grey[600],
),
),
When using a StatefulWidget you need to use "widget.property" in your implementation.
In your case
Expanded(
child: RectButton(
buttonChild: Text(widget.title1),
onPress: () {
setState(() {
selectedWeight = Weight.adjusted;
});
},
bgColor: selectedWeight == Weight.adjusted
? Colors.orange[600]
: Colors.grey[600],
),
),
Expanded(
child: RectButton(
buttonChild: Text(widget.title2),
onPress: () {
setState(() {
selectedWeight = Weight.adjusted;
});
},
bgColor: selectedWeight == Weight.adjusted
? Colors.orange[600]
: Colors.grey[600],
),
),
.....