flutterflutter-futurebuilder

Flutter: Navigate inside FutureBuilder


How to go to next screen in Futurebuilder? Basically, the conditions are: If snapshot has no data, [return CircularProgressIndicator()] else if 'keyword' = 'target', go to NextScreen, else return [ListView.builder]

     body: FutureBuilder(
          future: generatedText,
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (snapshot.data == null) {
              return const CircularProgressIndicator();
            } else if (widget.keyword == 'target') {
              // Go to NextScreen instead of 'ListView.builder'
              Navigator.push(context, MaterialPageRoute(builder: (context) => NextScreen(text: snapshot.data[7]), ),
              );
            } else {
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (BuildContext context, int index) {
                  return InkWell(onTap: () {
                      Navigator.push(context, MaterialPageRoute(builder: (context) => NextScreen(text: snapshot.data[index]),),
                      );
                    },
                    child: Text(snapshot.data[index],
                    ),
                  ); },
              );
            }  },  ),    

Solution

  • To schedule a callback that will be executed on the subsequent frame after the current frame has finished rendering, use WidgetsBinding.instance.addPostFrameCallback. A frame in the context of Flutter is an entire rendering cycle of the application, during which the framework updates the user interface by computing the layout, painting the widgets, and carrying out other operations.

    body: FutureBuilder(
      future: generatedText,
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          // Show a loading indicator while waiting for the data
          return CircularProgressIndicator();
        } else if (snapshot.hasError) {
          // Handle error state
          return Text('Error: ${snapshot.error}');
        } else if (widget.keyword == 'target') {
          // Use Navigator.pushReplacement to go to NextScreen instead of 'ListView.builder'
          WidgetsBinding.instance.addPostFrameCallback((_) {
            Navigator.pushReplacement(
              context,
              MaterialPageRoute(
                builder: (context) => NextScreen(text: snapshot.data[7]),
              ),
            );
          });
          return Container(); // Return an empty container while navigating
        } else {
          return ListView.builder(
            itemCount: snapshot.data.length,
            itemBuilder: (BuildContext context, int index) {
              return InkWell(
                onTap: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (context) => NextScreen(text: snapshot.data[index]),
                    ),
                  );
                },
                child: Text(snapshot.data[index]),
              );
            },
          );
        }
      },
    ),

    Try this code and let me know