How do I call method initState() from a stateless widget extending class?

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.

>Solution :

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();
  }
}

Leave a Reply