es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Navegue a la pantalla sin onPressed o algo similar.

Quiero navegar desde mi pantalla Launcher a mi pantalla secondScreen. Estoy tratando de hacerlo con:

Navigator.push(context, MaterialPageRoute(builder: (context) => SomeScreen()));

Quiero que esta función se ejecute cuando una variable específica en el state es modificada. Por lo tanto, no quiero que se ejecute con un onPressed: o un onTap:.

Si simplemente lo llamo en la función build del widget Launcher, obtengo el error:

Widget build(BuildContext context) {
return StoreConnector<AppState, AppState>(
converter: (store) => store.state,
builder: (context, state) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SomeScreen()));

setState() o markNeedsBuild() fue llamado durante la construcción.

Este widget de superposición no puede ser marcado como necesitando ser construido porque el marco ya está en el proceso de construir widgets. Un widget puede ser marcado como necesitando ser construido durante la fase de construcción solo si uno de sus padres está actualmente construyendo. Esta excepción está permitida porque el marco construye widgets padres antes que los hijos, lo que significa que siempre se construirá un descendiente sucio. De lo contrario, el marco podría no visitar este widget durante esta fase de construcción.
El widget en el que se llamó setState() o markNeedsBuild() fue: Overlay-[LabeledGlobalKey#39c7e]
state: OverlayState#759c1(entries: [OverlayEntry#f9b89(opaque: true; maintainState: false), OverlayEntry#1ff83(opaque: false; maintainState: true), OverlayEntry#5208b(opaque: false; maintainState: false), OverlayEntry#67aa9(opaque: false; maintainState: true)])
El widget que se estaba construyendo actualmente cuando se hizo la llamada ofensiva era: StreamBuilder
dirty
state: _StreamBuilderBaseState<AppState, AsyncSnapshot>#472c9

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para resolver este problema, necesitas separar la lógica de navegación del método de construcción del widget Launcher. Una forma de hacerlo es mediante el uso de un método didUpdateWidget en un widget separado que sea responsable de la navegación.

    Aquí hay un ejemplo de cómo hacerlo:

    1. Crea un nuevo widget de estado llamado NavigatorManager.
    2. Mueve el código Navigator.push al método didUpdateWidget de NavigatorManager.
    3. Pasa la variable state como parámetro a NavigatorManager.
    4. Agrega NavigatorManager como hijo del widget Launcher.

    Tu código debería verse algo así:

    class NavigatorManager extends StatefulWidget {
      final AppState state;
    
      const NavigatorManager({Key key, this.state}) : super(key: key);
    
      @override
      _NavigatorManagerState createState() => _NavigatorManagerState();
    }
    
    class _NavigatorManagerState extends State<navigatormanager> {
      @override
      void didUpdateWidget(NavigatorManager oldWidget) {
        super.didUpdateWidget(oldWidget);
    
        if (widget.state.specificVariable) {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (_) => SomeScreen()),
          );
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(); // Retorna un widget vacío o el widget deseado
      }
    }
    
    class Launcher extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return StoreConnector<appstate, appstate="">(
          converter: (store) => store.state,
          builder: (context, state) {
            return Scaffold(
              appBar: AppBar(
                title: Text('Launcher'),
              ),
              body: NavigatorManager(state: state),
            );
          },
        );
      }
    }
    

    Ahora, la lógica de navegación solo se llamará cuando se modifique specificVariable en el state.</appstate,>

Comments are closed.