Flutter - run code before or after execution of Function() that was passed as a parameter - flutter

Example: a widget, that accepts a Function() function as a parameter. Now i want to execute code inside this widget, when function is called somewhere above in hierarchy, before or after it. Is this possible?
Here is the button widget
class AppButton extends StatelessWidget {
final Function()? onPressed;
const AppButton(
{Key? key,required this.onPressed}): super(key: key);
#override
Widget build(BuildContext context) {
return ElevatedButton(onPressed: onPressed);
}
Here is how I call it
AppButton(
onPressed: () {
[some code]
},
),
Now the question is: is it possible to call a code, like setState inside the AppBar, before or after [some code] gets executed on tap? Like to inject code into onPressed inside AppButton?

Yes, it's possible, You should take the Function() function as an argument and in the Widget(e.g ElevatedButton in the property onPressed: function)
and in the Constructor get the function.
so, when you calling the widget it will ask for the function as well their you will give the function like this
YouWidgetName(function: () {
// here will be your code for that particular area.
}),

Related

How to access a variable data from the state of a flutter stateful widget from another stateful widget class's state

Hi guys I am facing a problem which I have tried to solve through multiple approaches but failed. I have a stateful widget class which has a variable in its state I need to access the data in this variable from another stateful widget's class's state, I have tried accessing the variable by creating a GlobalKey for the class which contains the variable, but when I access the variable I get null. Am I accessing the variable the wrong, way or is there a more appropriate way of doing it?
what i usually do in cases like this is i will define varableX globally so that i can access it from anywhere in my app. To do this install flutter_riverpod and define variableX like this:
final variableXProvider = StateProvider<bool>((ref)=> false/true);
inside your build method, you can access it like this
class StatefulWidget1 extends ConsumerStatefulWidget {
const StatefulWidget1({Key? key}) : super(key: key);
#override
ConsumerState<ConsumerStatefulWidget> createState() => _StatefulWidget1State();
}
class _StatefulWidget1State extends ConsumerState<StatefulWidget1> {
#override
Widget build(BuildContext context) {
//* watch variableX like this
final varibleX = ref.watch(variableXProvider.state).state;
return Scaffold(body: Column(
children: [
Text(varibleX),
//* to change the value of variableX you can do this
ElevatedButton(onPressed: (){
ref.read(variableXProvider.notifier).state = true/false;
}, child: Text('Change value'))
],),);
}
}
once you hit the button, the value changes without needing to call setState(). the ref object will automatically rebuild itself once it detects any changes.

Flutter: how to execute multiple functions in a single button

in Flutter I have made a custom button that does a small animation when pressing it. The issue is that when I add a VoidCallBack function, which is a parameter that I give to the button widget, to the same onTap, then the function does not get executed whilst the animation does.
I did find this question ( how do we execute two function in single button pressed in flutter) that seems to be similar to mine but I have tried the suggestions and they do not work for me.
Here is a code snippet of when Im trying to use the button widget:
MyButton (
onTap = () {
print(_isSelected);
setState(() {
_isSelected[0] = !_isSelected[0];
});
},
)
Also I dont know if it makes a difference but Ive tried it both with and without the setState part.
Then in the button itself I do:
onTap: () {
widget.onTap;
setState(() {
_clicked = !_clicked;
});
},
I also tried to do this, like in the other stackOverflow question which had the same result:
onTap: () => [
widget.onTap,
{
setState(() {
_clicked = !_clicked;
})
}
],
Though it does work if I only use the parameter: onTap: widget.onTap,
This is usually how I do it.
onTap: () {
widget.onTap();
your_function_here();
},
Declare function variable:
final Function onTap;
and call widget.onTap with round brackets as below:
onTap: (){
widget.onTap();
setState(() {
_clicked = !_clicked;
});
}
You need to declare a constructor which takes onTap function as a parameter.
class MyButton extends StatelessWidget {
final Function onTap;
const MyButton ({Key? key, this.onTap,}) : super(key: key);
}
Since the onTap parameter needs a function as argument, you simply write a function that runs your functions.
MyButton(
onTap: () {
your_function1();
your_function2();
},
)

How to acces parameter value from constructor in flutter?

I'm having trouble with accessing the value of a parameter from a constructor in my code. I access to this page from another one where I get the value of the parameter:
final route = MaterialPageRoute(
builder: (context) => AnadirJugadores(idPagina: respuesta['id'],));
Navigator.push(context, route);
This is the code of AnadirJugadores:
class AnadirJugadores extends StatefulWidget {
final String idPagina;
AnadirJugadores({required this.idPagina });
String cogerID() {
return this.idPagina;
}
#override
State<AnadirJugadores> createState() => _AnadirJugadoresState();
}
class _AnadirJugadoresState extends State<AnadirJugadores> {
#override
Widget build(BuildContext context) {
.... more code
ElevatedButton(
child: Text(idPartida), // this is the line of the error
onPressed: () {
final data = ClipboardData(text: '25342756374');
Clipboard.setData(data);
},
),
I'm trying to access the value of idPagina. How could I do that?
Thanks in advance.
When using stateful widgets you need to use widget to access the parameters.
child: Text(widget.idPartida),
In StatefulWidget your constructor exists in upper class (it's not in State class), so to access data in this constructor in your state class you should do this:
ElevatedButton(child: Text(widget.idPartida), ...),

Flutter ElevatedButton onPressed functions Avoid using unnecessary statements

I have a Flutter stateful widget inside a Stepper widget, and it looks like this:
The first step of the stepper widget has another widget as its content, and that widget is a stateful widget as below:
import 'package:flutter/material.dart';
class ConductorStart extends StatefulWidget {
const ConductorStart({
Key? key,
required this.continued,
}) : super(key: key);
final VoidCallback continued;
#override
ConductorStartState createState() => ConductorStartState();
}
class ConductorStartState extends State<ConductorStart> {
int _currentStep = 0;
bool _pressedButton = false;
void tapped() {
setState(() => _pressedButton = true);
}
#override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
if (!_pressedButton)
ElevatedButton(
onPressed: () {
tapped;
widget.continued;
},
child: const Text('Continue'),
)
else
const SizedBox.shrink(),
],
);
}
}
The ElevatedButton has two functions when called: tapped, and widget.continued. tapped should make the button disappear. and widget.continued is a function from the parent widget that is supposed to make the parent widget to continue to step 2 when clicked. Currently the two functions have a warning of Avoid using unnecessary statements, and they do not get executed properly. When I click the continue button. Nothing happens. What did I do wrong here?
I'll totally go with Pat9RB. Just posting it here as an answer for others to quickly find the relevant issue.
Adding just definitions helps for adding a callback parameter in the constructor.
For Eg.: onPressed: myOnPressed;
where, onPressed needs a VoidCallback, and myOnPressed is a VoidCallback argument.
But, you need to call the function in order to execute it from any other function body.
Either call using .call() method, like, tapped!.call(); or append with callback syntax (), like, tapped();

Pass callback Function as Parameter to Widget while keeping Lint Rules "argument_type_not_assignable"

In my widget I pass a function callback as a parameter to the widget:
onTap: onTapRestaurantItemCallback
Out in the screen widget, which contains the widget above, I then execute the function callback:
onTapRestaurantItemCallback: () { // Handling the callback method }
I am using Lint for Dart/Flutter to check my code:
https://pub.dev/packages/lint
The linter is not happy with my function parameter and gives me an error, I am violating the rule:
argument_type_not_assignable
"The argument type 'Function' can't be assigned to the parameter type 'void Function()'"
https://dart.dev/tools/diagnostic-messages#argument_type_not_assignable
Apparently the problem is that the widgets "onTap" expects void, whereas the callback returns a Future.
I can make the error go away in the widget by writing:
onTap: () => onTapRestaurantItemCallback
But then my function callbacks stop working.
Do you know how I can pass a function callback to my widget like I do and still keep the
argument_type_not_assignable
lint rule?
Below I paste a more full code on the scenario I have described above:
// WIDGET USED BY OTHER WIDGET BELOW
class RestaurantItem extends StatelessWidget {
// FUNCTION CALLBACK
final Function onTapRestaurantItemCallback;
const RestaurantItem({
// FUNCTION CALLBACK
#required this.onTapRestaurantItemCallback,
});
#override
Widget build(BuildContext context) {
return GestureDetector(
// FUNCTION CALLBACK
onTap: onTapRestaurantItemCallback,
// CONTAINING SCREEN WIDGET - USING WIDGET ABOVE
// .... //
RestaurantItem(
// FUNCTION CALLBACK
onTapRestaurantItemCallback: () => { // Handling the callback method }
),