-1

I have a splash screen in my homepage activity which should then redirect to my second activity:

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState(){
    super.initState();
    Timer(const Duration(seconds: 3),
            ()=>Navigator.pushReplacement(context,
            MaterialPageRoute(builder:
                (context) =>
                SecondScreen()
            )
        )
    );
  }
  @override
  Widget build(BuildContext context) {
    return Container(
        color: Colors.white,
        child:FlutterLogo(size:MediaQuery.of(context).size.height)
    );
  }
}
class SecondScreen extends StatelessWidget { //checking if internet connection exists here
  late StreamSubscription subscription;
  var isDeviceConnected = false;
  bool isAlertSet = false;
  @override
  void initState(){
    getConnectivity();
    super.initState(); //initState() is undefined
  }
  getConnectivity() =>
      subscription = Connectivity().onConnectivityChanged.listen(
            (ConnectivityResult result) async {
          isDeviceConnected = await InternetConnectionChecker().hasConnection;
          if (!isDeviceConnected && isAlertSet == false) {
            showDialogBox();
            setState(() => isAlertSet = true); //setState() is undefined
          }
        },
      );
  @override
  void dispose() {
    subscription.cancel();
    super.dispose(); //dispose() is undefined
  }
  @override
  Widget build(BuildContext context) {
      return Scaffold(
          appBar: AppBar(
            title: Row(
                mainAxisAlignment:MainAxisAlignment.center,
                children:[
                  Image(
                    image: const AssetImage('images/logo.png'),
                    height: AppBar().preferredSize.height,),
                  const SizedBox(
                    width: 15,
                  ),
                  Text(
                      widget.title
                  ),
                ]
            )
        )
     );
  }
  showDialogBox() => showCupertinoDialog<String>(
    context: context,
    builder: (BuildContext context) => CupertinoAlertDialog(
      title: const Text('No internet connection'),
      content: const Text('Please make sure you have an active internet connection to continue'),
      actions: <Widget>[
        TextButton(
          onPressed: () async {
            Navigator.pop(context, 'Cancel');
            setState(() => isAlertSet = false);
            isDeviceConnected =
            await InternetConnectionChecker().hasConnection;
            if (!isDeviceConnected && isAlertSet == false) {
              showDialogBox();
              setState(() => isAlertSet = true);
            }
          },
          child: const Text('OK'),
        ),
      ],
    ),
  );
}

The flow is such that, in the homepage activity a splash screen will open and then it will redirect to the second activity which will check if the user has an active internet connection.

I tried changing the SecondScreen to statefulWidget, but I still keep getting the same error.

5
  • Does this answer your question? How to run code when Stateless widget is created Commented Nov 9, 2022 at 11:16
  • No, I didn't understand the solution mentioned in the post above. Commented Nov 9, 2022 at 11:24
  • because there is no initState in a StatelessWidget ! Commented Nov 9, 2022 at 11:28
  • 2
    Just change the SecondScreen to statefulWidget and you will can use initState method Commented Nov 9, 2022 at 11:31
  • @GNassro I tried that, but it still shows the same errors. Please have a look into my updated post Commented Nov 9, 2022 at 11:45

2 Answers 2

4

Stateless: A stateless widget is like a constant. It is immutable. If you want to change what is displayed by a stateless widget, you'll have to create a new one.

Stateful: Stateful widgets are the opposite. They are alive and can interact with the user. Stateful widgets have access to a method named setState, which basically says to the framework "Hello, I want to display something else. Can you redraw me please ?".

A stateless widget can only be drawn once when the Widget is loaded/built and cannot be redrawn based on any events or user actions.

This kind of widget has no state, so they can’t change according to an internal state, they only react to higher widget changes.

more information read this documentation StatefulWidget and StatelessWidget

convert in stateful widget

class SecondScreen extends StatefulWidget {
  const SecondScreen({Key? key}) : super(key: key);

  @override
  State<SecondScreen> createState() => _SecondScreenState();
}

class _SecondScreenState extends State<SecondScreen> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

So what's the workaround? How do I call initState() in my superclass Secondscreen?
you must be change the SecondScreen to statefulWidget and use initState method
I tried that, but I still keep getting the same error
i'm update my answer see and put your code
1

there is no initState in a stateless widget but you can call a function after rebuild of a stateless widget using this:

  


class SecondScreen extends StatelessWidget {
    @override
  Widget build(BuildContext context) {

WidgetsBinding.instance?.addPostFrameCallback((_) {
    // do something
    print("Build Completed"); 
  });
  
    return Container(
        color: Colors.blue,
        child: WhatEverWidget()
    );
  }
}

2 Comments

we are just answering your question How do I call method initState() from a stateless widget. if you are looking for a different answer then create another question for that. you need to learn how to ask a question for you to be able to get the right answer. otherwise, you are just wasting other people's time asking a question but seeking a different thing.
Sorry for that, I have updated the code, please have a look