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(
....
);}} ```
Related
So i have this toggle() method in the Stateful SideBar class
class SideBar extends StatefulWidget {
const SideBar({super.key});
#override
State<SideBar> createState() => _SideBarState();
}
class _SideBarState extends State<SideBar> with SingleTickerProviderStateMixin{
void toggle() {
if (_controller.isCompleted) {
_controller.reverse();
}
else {_controller.forward();}
}
}
and i want to use it in
class SideBarWidget extends StatelessWidget {
SideBarWidget({Key? key}) : super(key: key);
final SideBar sideBarWidget = SideBar(...);
void toggle() {
// here i want to use the toggle() method
}
#override
Widget build(BuildContext context) {
return sideBarWidget;
}
}
I cannot use sideBarWidget.toggle()
I also cannot pass it as a parameter becasue the _controller is in the SideBar() widget
There are many ways, but the most common and simple is to create an instance of the SideBar class inside the SideBarWidget class, for example:
var side = SideBar();
And then you can access the toggle() method like this: side.toggle().
remove underscore from SideBarState
to use method of SideBarState in SideBarWidget use: SideBarState().toggle();
**screen1.dart**
class ParentWidget extends StatefulWidget {
const ParentWidget({Key? key}) : super(key: key);
#override
State<ParentWidget> createState() => ParentWidgetState();
}
class ParentWidgetState extends State<ParentWidget> {
void printData() {
print("parent");
}
#override
Widget build(BuildContext context) {
return const Placeholder();
}
}
**screen2.dart**
import 'package:demo/screen_1.dart';
import 'package:flutter/material.dart';
class ChildWidget extends StatelessWidget {
const ChildWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
ParentWidgetState().printData();
return const Placeholder();
}
}
One way is to give the SideBar a GlobalKey and get the state from the key afterwards. An example:
class SideBar extends StatefulWidget {
const SideBar({super.key});
#override
State<SideBar> createState() => SideBarState();
}
class SideBarState extends State<SideBar> with SingleTickerProviderStateMixin{
#override
Widget build(BuildContext context) {
return Container();
}
void toggle() {
print('toggle');
}
}
class SideBarWidget extends StatelessWidget {
SideBarWidget({Key? key}) : super(key: key);
final GlobalKey<SideBarState> sideBarKey = GlobalKey();
late final SideBar sideBarWidget = SideBar(key: sideBarKey);
void toggle() {
sideBarKey.currentState?.toggle();
}
#override
Widget build(BuildContext context) {
return Column(
children: [
TextButton(onPressed: toggle, child: const Text('click')),
sideBarWidget,
],
);
}
}
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
);
}
}
How can I pass generic type to the State of a StatefulWidget, Here I want to use my generics in myMethod<T>
class MyWidget<T> extends StatefulWidget {
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
#override
Widget build(BuildContext context) {
return Container();
}
myMethod<T>(){
}
}
You just provide the type in your state full widget and then pass it way down to its state:
class MyWidget<T> extends StatefulWidget {
#override
_MyWidgetState<T> createState() => _MyWidgetState<T>();
}
class _MyWidgetState<T> extends State<MyWidget<T>> {
#override
Widget build(BuildContext context) {
return Container();
}
myMethod<T>() {
}
}
Usage:
MyWidget<String>()
_MyWidgetState need to extends State<MyWidget<T>> not just State<MyWidget> and then you can use T within _MyWidgetState
Here's how the Flutter team solves this issue inside the FutureBuilder widget. Instead of having a return type of _MyWidgetState<T> for the createState(), you would need State<MyWidget<T>>.
State<MyWidget<T>> createState() => _MyWidgetState<T>();
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(
);
}
}
I have an app that looks like this
class MainScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() => MainScreenState();
}
class MainScreenState extends State<MainScreen> {
#override
Widget build(BuildContext context) {
return new Container(
child: FlatButton(
onPressed:() {
// Want pop up to launch
},
),
)
}
}
class PopUp extends StatefulWidget {
PopUp({
this.postId
})
#override
State<StatefulWidget> createState() => PopUpState();
}
class PopUpState extends State<PopUp> {
// api logic
#override
Widget build(BuildContext context) {
return new Dialog()
}
}
Is it possible for me to overlay the PopUp widget on top of the MainScreen Widget without using showDialog ? Since i'm trying to make the PopUp stateful in that it processes and rerenders itself depending on the processed data ?