The argument type 'Function' can't be assigned to the parameter type 'void Function()? - flutter

I am getting this error on answer.dart
"lib/answer.dart:15:20: Error: The argument type 'Function' can't be assigned to the parameter type 'void Function()?'."
Here are the files:
main.dart
import 'package:flutter/material.dart';
import 'Questions.dart';
import 'answer.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MyAppState();
// ignore: dead_code
throw UnimplementedError();
}
}
class _MyAppState extends State<MyApp> {
var _questionIndex = 0;
var questions = [
'what\'s your fav color?',
'what\'s your fav Food?',
'what\'s your fav Animal?'
];
void _answerQuestion() {
setState(() {
_questionIndex++;
if (_questionIndex >= questions.length) _questionIndex = 0;
});
print(_questionIndex);
print(questions.length);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My Flutter App'),
),
body: Column(
children: [
Question(questions[_questionIndex]),
Answer(_answerQuestion),
Answer(_answerQuestion),
Answer(_answerQuestion),
],
),
),
);
}
}
answer.dart
import 'package:flutter/material.dart';
class Answer extends StatelessWidget {
final Function selectHandler;
Answer(this.selectHandler);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: ElevatedButton(
child: Text('Ans 1'),
onPressed: selectHandler,
style: ElevatedButton.styleFrom(
primary: Colors.red,
),
),
);
}
}
Questions.dart
import 'package:flutter/material.dart';
class Question extends StatelessWidget {
final String questionText;
Question(this.questionText);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
child: Text(
questionText,
style: TextStyle(fontSize: 28),
textAlign: TextAlign.center,
),
);
}
}
Now I have tried to look at the logic, constructor is properly defined in the answer.dart file and it has been handeled well in the main.dart as well.
I am still learning and running out of options to solve this error.
can anyone please help to resolve this error.

Change it to this:
onPressed: ()=> selectHandler()

Related

Argument type 'Function' can't be assigned to the parameter type 'void'

I am passing a call back function from my child file to the parent file, in the elevated button class, I am passing the function in the class (in the child file )to the named parameter on pressed, but I am getting the error in the question above, while it worked for the tutorial I am using(academind).
How do I solve this?
CHILD file
class Answer extends StatelessWidget {
final Function selectHandler;
Answer(this.selectHandler);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: ElevatedButton(
child: Text('Answer 1'),
style: ElevatedButton.styleFrom(
primary: Colors.lightGreen
),
onPressed: selectHandler,
),
);
}
}
PARENT file
// ignore_for_file: prefer_const_constructors, avoid_print, prefer_const_literals_to_create_immutables, must_be_immutable, prefer_const_constructors_in_immutables
import 'package:flutter/material.dart';
import './question.dart';
import './answer.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
MyApp({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() {
// ignore: todo
// TODO: implement createState
return _MyAppState();
}
}
class _MyAppState extends State <MyApp>{
var _questionsIndex = 0;
var questions = [
'What\'s your favourite book',
'What\'s your favourite colour',
'What\'s our favourite poem',
];
void _answerQuestion() {
setState(() {
_questionsIndex = _questionsIndex + 1;
if (_questionsIndex >= questions.length) _questionsIndex = 0;
});
print(_questionsIndex);
print(questions.length);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('My First App'),),
body: Column(
children: [
Question(
questions[_questionsIndex],
),
Answer(_answerQuestion),
Answer(_answerQuestion),
Answer(_answerQuestion),
],
)
),
);
}
}
Change Function to
void Function functionName(){}
or
VoidCallback functionName(){}
Same issue i have faced after updating this it is working
import 'package:flutter/material.dart';
class Answer extends StatelessWidget {
final VoidCallback clickFunction;
const Answer(this.clickFunction,{Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(5),
child: RaisedButton(
padding: const EdgeInsets.all(10),
color: Colors.blue,
onPressed: clickFunction,
child: const Text("This is texxt"),
));
}
}
this is worked for me
final void Function()? FunctionName;

Flutter How to pass a parameter (int) to callbacks?

How can I pass a parameter wit callback in Flutter?
I have two files main.dart and block.dart. My goal is to add an int (12 for example) to myCallback in block.dart to use it in main.dart in the function whatToDo (instead of print ('Should receive the Value from myCallback');)
Here is the code of the main.dart File:
import 'package:flutter/material.dart';
import 'block.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MainBlock(),
);
}
}
class MainBlock extends StatefulWidget {
#override
_MainBlockState createState() => _MainBlockState();
}
class _MainBlockState extends State<MainBlock> {
void whatToDo() {
print('Should receive the Value from myCallback');
}
#override
Widget build(BuildContext context) {
// print(getraenke.asMap());
// print(getraenke.asMap().keys);
// print(getraenke);
return Scaffold(
body: Container(
margin: EdgeInsets.all(30.0),
color: Color(0xFF122C39),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Block(
myCallback: whatToDo,
),
),
],
),
),
);
}
}
And here is the Code from block.dart with the callback:
import 'package:flutter/material.dart';
class Block extends StatelessWidget {
final Function myCallback;
Block({this.myCallback});
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(10.0),
color: Color(0xFF722662),
child: Center(
child: GestureDetector(
onTap: myCallback,
child: Text(
'Button',
style: TextStyle(
color: Color(0xFFFFFFFF),
fontSize: 22.0,
),
),
),
),
);
}
}
If I understood it correctly, You want your function to accept a parameter.
do it like this.
class Block extends StatelessWidget {
final Function(int num) myCallback;
Block({this.myCallback});
and when you call it, you provide it with the parameter
GestureDetector(
onTap:()=> myCallback(12),
child: ...
and finally you can access it from your main
void whatToDo(int num) {
print(num);
}
Simple way without any advanced topic. Better read some articles about state management. Official documentation.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MainBlock(),
);
}
}
class MainBlock extends StatefulWidget {
#override
_MainBlockState createState() => _MainBlockState();
}
class _MainBlockState extends State<MainBlock> {
void whatToDo(int value) {
print('Should receive the Value from myCallback');
print(value);
}
#override
Widget build(BuildContext context) {
// print(getraenke.asMap());
// print(getraenke.asMap().keys);
// print(getraenke);
return Scaffold(
body: Container(
margin: EdgeInsets.all(30.0),
color: Color(0xFF122C39),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Block(
myCallback: whatToDo,
),
),
],
),
),
);
}
}
class Block extends StatelessWidget {
final void Function(int) myCallback;
Block({required this.myCallback});
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(10.0),
color: Color(0xFF722662),
child: Center(
child: GestureDetector(
onTap: ()=>myCallback(12),
child: Text(
'Button',
style: TextStyle(
color: Color(0xFFFFFFFF),
fontSize: 22.0,
),
),
),
),
);
}
}
in main.dart:
void whatToDo(int value) {
print('the value is $value');
}
in block.dart:
class Block extends StatelessWidget {
final ValueChanged<int> myCallback;
Block({required this.myCallback});
#override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(10.0),
color: const Color(0xFF722662),
child: Center(
child: GestureDetector(
onTap: () => myCallback(100),
child: const Text(
'Button',
style: TextStyle(
color: Color(0xFFFFFFFF),
fontSize: 22.0,
),
),
),
),
);
}
}
I add more info to Ethsan Askari's answer.
You can define your custom callback and reuse it throughout your app.
typedef OnWhatToDoCallback = Function(int value);
class Block extends StatefulWidget {
const Block({
Key? key,
required this.onWhatToDo,
}) : super(key: key);
final OnWhatToDoCallback onWhatToDo;
...
}

Error: The argument type 'Function' can't be assigned to the parameter type 'void Function()?'.'Function' is from 'dart:core'.onPressed: selectHandler

main.dart
import 'package:flutter/material.dart';
import './questions.dart';
import './answer.dart';
void main() {
runApp(AskMe());
}
class AskMe extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _AskMeState();
}
}
class _AskMeState extends State<AskMe> {
var _next_ques = 0;
void _Response() {
setState(() {
_next_ques += 1;
});
print(_next_ques);
}
#override
Widget build(BuildContext context) {
var questions = ["What is your Name ?", "What is your favourite color ?"];
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Ask Me"),
),
body: Column(
children: [
Questions(questions[_next_ques]),
Answer(_Response),
Answer(_Response),
Answer(_Response),
],
),
),
);
}
}
questions.dart
import 'package:flutter/material.dart';
class Questions extends StatelessWidget {
final String questions;
Questions(this.questions);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.all(20),
child: Text(
questions,
style: TextStyle(fontSize: 28),
textAlign: TextAlign.center,
),
);
}
}
answer.dart
import 'package:flutter/material.dart';
class Answer extends StatelessWidget {
final Function selectHandler;
Answer(this.selectHandler);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.all(10),
child: RaisedButton(
color: Colors.blueGrey,
child: Text("Question 1"),
onPressed: selectHandler,
),
);
}
}
The above code is for basic app that consists of 3 buttons for the questions shown as textview and clicking on button will display next question. The issue i'm facing is while making custom dart function in answer.dart i'm not able to call the pointer to the function _Response which is present in main.dart as it gives the error mentioned in the title. Thanks for the help.
Define function type like this:
class Answer extends StatelessWidget {
final Function() selectHandler;
...

Instantiate child button with given value, but it is not changed

I am learning new Dart/Flutter and try to make my own exercise. I believe I am missing something fundamental here.
Problem:
My button is showing question mark. But I instantiate it with value already
Question:
How to instantiate button with given text?
import 'package:complete_guide/question.dart';
import 'package:flutter/material.dart';
import 'answer.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int index = 0;
List<String> questions = [
"How may I help you?",
"What is you favorite dog?"
];
void _answerQuestion(){
setState(() {
index = index + 1;
});
print(index);
}
void showText(inputText){
print(inputText);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Stay Strong")
),
body: Center(
child: Column(
children: [
Question(questions[index]),
Answer("iddqd", _answerQuestion),
Answer("idkfa", _answerQuestion),
Answer("show me the money", _answerQuestion),
],
),
),
)
);
}
}
class Answer extends StatelessWidget {
final Function selectHandler;
String answerText = "?";
Answer(answerText, this.selectHandler);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: ElevatedButton(
child: Text(answerText),
onPressed: selectHandler,
)
);
}
}
class Question extends StatelessWidget {
final String questionText;
Question(this.questionText);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.all(10),
child: Text(
this.questionText,
style: TextStyle(fontSize: 20, color: Colors.orange),
textAlign: TextAlign.center,
),
);
}
}
Please do not ignore analyzer warnings. They are there for a reason.
First, answerText should be marked as final. It should not be initialized so that it can be assigned a value in the constructor. Finally, you need to use the this. syntax that you've used for all of your other constructor parameters.
There is also no need of providing a default value of '?' for answerText because the constructor uses it as a required parameter, so that default value will never be used.
class Answer extends StatelessWidget {
final Function selectHandler;
final String answerText;
Answer(this.answerText, this.selectHandler);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: ElevatedButton(
child: Text(answerText),
onPressed: selectHandler,
)
);
}
}

Flutter / Dart / NoSuchMethodError

I have not been able to fix the error for 2 hours. Maybe one of you can help me. You can find a photo below.
What the Debug Console also tells me is:
[ The following NoSuchMethodError was thrown building MyApp (dirty, state: _MyAppState#c7f7e):
I/flutter (17681): The method 'map' was called on null.
I/flutter (17681): Receiver: null
I/flutter (17681): Tried calling: map<Answer>(Closure: (String) => Answer)]
import 'package:flutter/material.dart';
import './question.dart';
import './answer.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
var _questionIndex = 0;
void _answerQuestion() {
setState(() {
_questionIndex = _questionIndex + 1;
});
print(_questionIndex);
}
#override
Widget build(BuildContext context) {
const questions = const [
{
'questionText': 'What\'s your favorite color?',
'answer': ['Black', 'Yellow', 'white', 'green'],
},
{
'questionText': 'What\'s your favorite animal?',
'answer': ['Lion', 'Rabbit', 'Snake', 'Elephant'],
},
{
'questionText': 'What\'s your favorite instructor?',
'answer': ['Flo', 'Viona', 'Flint', 'Flo'],
},
];
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My First App!'),
),
body: Column(
children: [
Question(
questions[_questionIndex]['questionText'],
),
...(questions[_questionIndex]['answers'] as List<String>)
.map((answer) {
return Answer(_answerQuestion, answer);
}).toList()
],
),
),
);
}
}
import 'package:flutter/material.dart';
//import './main.dart';
class Question extends StatelessWidget {
final String questionText;
Question(this.questionText);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.all(10),
child: Text(
questionText,
style: TextStyle(fontSize: 28),
textAlign: TextAlign.center,
),
);
}
}
import 'package:flutter/material.dart';
class Answer extends StatelessWidget {
final Function selectHandler;
final String answerText;
Answer(this.selectHandler, this.answerText);
#override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
child: RaisedButton(
color: Colors.blue,
textColor: Colors.white,
child: Text(answerText),
onPressed: selectHandler,
),
);
}
}
That shows me the app
There are no key called answers in your map. Instead it is called answer. So questions[_questionIndex]['answers'] will return null since the [] operator for Map is documented as:
Returns the value for the given key or null if key is not in the map.
https://api.dart.dev/stable/2.8.3/dart-core/Map/operator_get.html
Its due to higher Flutter version you are using. Do the change in pubspec.yaml file. Change the version to 2.11.0
environment:
sdk: ">=2.11.0 <3.0.0"