I want to access this method updateCounter() from another class. How should I call it? Or how can I instantiate _HomePageState?
Here is my code :
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
static int i=0;
void updateCounter(int counter) {
print(counter);
setState(() {
i=counter;
});
}
#override
Widget build(BuildContext context) {
return Container(
);
}
}
Related
I am a flutter beginner, I want to create a flutter application that contains two pages, I encounter an error that I do not understand.
Here is my code:
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
MyApp({super.key});
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: FirstPage(),
);
}
}
class FirstPage extends StatefulWidget {
FirstPage({super.key});
#override
State<MyApp> createState() => _FirstPageState();
}
class _FirstPageState extends State<MyApp> {
String bottonName = 'click';
int currentIndex = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
....
);}}
L'erreur est la suivante:
StatefulWidget.createState must return a subtype of State<FirstPage>
The createState function for FirstPage returned a state of type _FirstPageState, which is not a subtype of State<FirstPage>, violating the contract of createState.
the state type of your First screen is from another widget. change it with this:
class FirstPage extends StatefulWidget {
FirstPage({super.key});
#override
State<FirstPage> createState() => _FirstPageState();
}
class _FirstPageState extends State<FirstPage> {
String bottonName = 'click';
int currentIndex = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
....
);}} ```
I want to call method from another class which contains setState. I got some error in page 2like this
This happens when you call setState() on a State object for a widget that hasn't been inserted into the widget tree yet. It is not necessary to call setState() in the constructor, since the state is already assumed to be dirty when it is initially created.
I've read this answer, but I didnt get it on my case. Any Ideas? Thank you
class Page1 extends StatefulWidget {
#override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
#override
void initState(){
Page2().method();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
),
);
}
}
class Page2 extends StatefulWidget {
method() => createState().methodInPage2();
#override
_Page2State createState() => _Page2State();
}
class _Page2State extends State<Page2> {
Future<List<String>> methodInPage2() async{
//error here
setState(){
//setState here,
}
}
#override
Widget build(BuildContext context) => Container();
}
There are two stateful widgets, I want to call a method present in one class from another onTap. Below is the brief code:
class FirstClass extends StatefulWidget {
final String total;
FirstClass(this.total);
#override
_FirstClassState createState() => _FirstClassState();
}
class _FirstClassStateState extends State<FirstClassState> {
Model getModel(abc){ //Model class is in another dart file
Model nModel = new Model();
nModel.n1 = abc;
}
next(){
setstate(){some code}
}
SecondClass (
model: getModel(s),
num:1,
)
}
class SecondClass extends StatefulWidget {
final Model model;
final int num;
SecondClass({#required this.model, #required this.num});
#override
_SecondClassState createState() => _SecondClassState();
}
class _SecondClassState extends State<SecondClass> {
onTap(){ //I have to call the method next() from here }
}
========================================================================
Yes,the SecondClass is present inside widget tree of FirstClass
You can do it like this. If your SecondClass is within the FirstClass widget tree. You can create a Function onTap() constructor on the SecondClass and used that onTap on the FirstClass
class FirstClass extends StatefulWidget {
#override
_FirstClassState createState() => _FirstClassState();
}
class _FirstClassState extends State<FirstClass> {
void next() {
setState(() {
// SOME CODE
});
}
#override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
SecondClass(
onTap: () => next(),
)
],
),
);
}
}
class SecondClass extends StatefulWidget {
final Function onTap;
const SecondClass({Key key, this.onTap}) : super(key: key);
#override
_SecondClassState createState() => _SecondClassState();
}
class _SecondClassState extends State<SecondClass> {
#override
Widget build(BuildContext context) {
return Center(
child: ElevatedButton(
onPressed: () => widget.onTap(),
child: Text("BUTTON"),
),
);
}
}
I have created a custom StatefulWidget that takes a Widget as an argument.
import 'package:flutter/material.dart';
class CustomWidget extends StatefulWidget {
final Widget myWidget;
CustomWidget({this.myWidget});
#override
_CustomWidgetState createState() => _CustomWidgetState();
}
class _CustomWidgetState extends State<CustomWidget> {
#override
Widget build(BuildContext context) {
return Container(
child: widget.myWidget(name: 'ASAD'), //I want to achieve this
);
}
}
I'm passing another StatefulWidget named Profile as that argument widget. Now I want to access that passed widget's constructor.
import 'package:flutter/material.dart';
class Profile extends StatefulWidget {
final String name;
Profile({this.name});
#override
_ProfileState createState() => _ProfileState();
}
class _ProfileState extends State<Profile> {
#override
Widget build(BuildContext context) {
return Center(child: Text('${widget.name}'),);
}
}
I'm using the CustomWidget which takes a widget as argument here
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: CustomWidget(myWidget: Profile(),) //I don't want to pass the argument here
);
}
}
I was able to accomplish something like this using typedef but it started throwing an error.
typedef CustomCallBack = Widget Function({String name});
class CustomWidget extends StatefulWidget {
final CustomCallBack myWidget;
CustomWidget({this.myWidget});
#override
_CustomWidgetState createState() => _CustomWidgetState();
}
class _CustomWidgetState extends State<CustomWidget> {
#override
Widget build(BuildContext context) {
return Container(
child: widget.widget(name: 'ASAD'), //I'm able to access the constructor here but now I get an error.
);
}
}
Error
error: The argument type 'Profile' can't be assigned to the parameter type 'Widget Function({String name})'. (argument_type_not_assignable
Note: Based on the app that I'm working on but cannot share code, I have recreated this scenario and is same as far as the issue is concerned.
Try the change this line in the CustomWidget widget,child: widget.widget(name: 'ASAD'), for the widget that you are passing only, without putting the (name: 'ASAD').
So when you pass the Profile Widget, that's when you must specify the value of the name parameter!
body: CustomWidget(myWidget: Profile(name: 'ASAD'),)
please try to use this :
import 'package:flutter/material.dart';
typedef CustomCallBack = Widget Function(String name);
class CustomWidget extends StatefulWidget {
final CustomCallBack myWidget;
CustomWidget({this.myWidget});
#override
_CustomWidgetState createState() => _CustomWidgetState();
}
class _CustomWidgetState extends State<CustomWidget> {
#override
Widget build(BuildContext context) {
return Container(
child: widget.myWidget(
'ASAD'), //I'm able to access the constructor here but now I get an error.
);
}
}
class Profile extends StatefulWidget {
final String name;
Profile({this.name});
#override
_ProfileState createState() => _ProfileState();
}
class _ProfileState extends State<Profile> {
#override
Widget build(BuildContext context) {
return Center(
child: Text('${widget.name}'),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: CustomWidget(
myWidget: (name) => Profile(
name: name,
),
) //I don't want to pass the argument here
);
}
}
I am building a podcasting type app, so need to call the record, stop, and play functions in many places, I created the methods, but difficulty to call these methods in other places.
main.dart
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String statusText = "";
bool isComplete = false;
void startRecord() //Need to call all of these method in coming stateful widgets
void stopRecord() //
void pauseRecord()//
void resumeRecord()//
void play() //
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Builder(
builder: (context) => Scaffold(
drawer: Drawer(
elevation: 2.0,
child: ListView(
children: <Widget>[
ListTile(
title: Text('Home'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return MyApp();
},
),
);
},
),
//more code is here
Expanded(
child: GestureDetector(
child: IconButton(
icon: Icon(Icons.mic),
color: Colors.white,
iconSize: 40,
onPressed: () async {
startRecord();
}),
),
),
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return MaterialApp(
onPressed: () {
startRecord()
// need to call the method here.
}
Pressed: () {
stopRecord()
// need to call the method here.
}
Pressed: () {
play()
// need to call the method here.
}
),
}
Need to call all the methods from a first stateful widget for bottom stateful widgets
also, need to call these methods for other classes when code progress
both stateful widgets are in the main.dart. I could not call the method from the first class for the second stateful widget
This is not a rocket science, just a simple line of code, and you are done.
What you have to do, is to just call the MyHomePage() and let it accept the startRecording() to be used inside the Widget
1. Passing the data from MyApp() to MyHomePage()
#override
Widget build(BuildContext context) {
return MaterialApp(
// here you pass the your function
home: MyHomePage(onPressed: startRecording)
);
}
2. Receiving the data in MyHomePage()
class MyHomePage extends StatefulWidget {
// let it accept a function type onPressed argument
final Function onPressed;
// constructor
MyHomePage({Key key, this.onPressed}): super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return MaterialApp(
// simply call the onPressed which received your startRecording() from MyApp
onPressed: () => widget.onPressed()
}
You can get the state of a parent widget using the BuildContext of the child widget like so:
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
static _MyAppState of(BuildContext context) {
return context.findAncestorStateOfType<_MyAppState>();
}
}
class _MyAppState extends State<MyApp> {
String statusText = "";
bool isComplete = false;
void startRecord() {
print('Hello');
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
MyApp.of(context).startRecord();
return Scaffold(
body: Placeholder(),
);
}
}
Simply define that function outside the class as a stand-alone function like this But if you want to call from inside the class. Heres the code.
inside a different class as a static function:
onPressed: () {
_MyAppState().startRecord(); //call using the class name.
}
Like this inside your onpressed Statement.
Should work.
Or else what you can do is define the function outside the class. Then use it where ever you want. Like this:
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
void startRecord(){
.
.
.
} /// Like here outside the class
class _MyAppState extends State<MyApp> {
String statusText = "";
bool isComplete = false;
#override
Widget build(BuildContext context) {
return MaterialApp(.....
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return MaterialApp(
onPressed: () {
startRecord(); // call Here as follows.
}),
}