【问题标题】:Flutter navigation by route name in statefull widget在有状态的小部件中按路由名称进行颤振导航
【发布时间】:2019-12-13 13:49:52
【问题描述】:

我正在尝试使用导航转到另一个页面,但出现错误;

使用不包含 导航器。

我只是想继续下一页,我关注了这个无状态小部件的颤振文档,但是如何处理状态完整小部件。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  State createState() => new MyApp1();
}

class MyApp1 extends State<MyApp> {
  List<Widget> _listSection = [];

  Widget build(BuildContext context) {
   return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Share IDEASS',
      initialRoute: '/',
  routes: {
    '/second': (context) => SecondScreen(),
  },
      home: Scaffold(
        appBar: AppBar(
          title: Text('IDEAS'),
        ),
        body: Container(
          child: Stack(
            children: [
              floatingButton(),
            ],
          ),
        ),
      ),
    );
  }



  Widget floatingButton() {
    return Container(
      padding: const EdgeInsets.all(30),
      alignment: Alignment.bottomRight,
      child: FloatingActionButton(
        onPressed: () {
            Navigator.pushNamed(context, "/SecondScreen");
          },
        child: Text("+"),
        backgroundColor: Colors.blue,
      ),
    );
  }
}
class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Route"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Go back!'),
        ),
      ),
    );
  }
}

【问题讨论】:

  • 只需将“SecondScreen”替换为“second”
  • @HarshvardhanJoshi 再次出现同样的错误

标签: flutter flutter-layout


【解决方案1】:

您应该使用您创建的命名路由。

Widget floatingButton(BuildContext context) { // added context as a parameter
    return Container(
      padding: const EdgeInsets.all(30),
      alignment: Alignment.bottomRight,
      child: FloatingActionButton(
        onPressed: () {
            Navigator.pushNamed(context, "/second"); // Changed this to use the named route
          },
        child: Text("+"),
        backgroundColor: Colors.blue,
      ),
    );
  }
}

然后使用下面的

body: Container(
          child: Stack(
            children: [
              floatingButton(context),
            ],
          ),
        ),

【讨论】:

    【解决方案2】:

    这里的情况是floatingButton() 使用带有导航器的上下文来推送给定的页面路由。但是使用的上下文是在它自己的父 Widget(MaterialApp) 中提供的,它不包括导航器,因此会出现错误。

    所以,试试这个方法: 将 Home 小部件与 MaterialApp 分开,如下所示:

    return MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'Share IDEASS',
          initialRoute: '/',
          routes: {
            '/second': (context) => SecondScreen(),
          },
          home: HomePage(),
        );
    

    创建一个包含 Scaffold 的无状态小部件:

    class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('IDEAS'),
          ),
          body: Container(
            child: Stack(
              children: [
                floatingButton(),
              ],
            ),
          ),
        );
      }
    }
    

    希望对您有所帮助。如果这不起作用,请告诉我。

    【讨论】:

    • 浮动按钮是有状态小部件类的功能,我如何在无状态类中调用它?
    • 知道了,我只是把它放在课外
    • 您使用了 home: HomePage(),我在我家的脚手架中添加了不同的部分,这些部分正在更改状态的子属性下,我现在如何添加这些部分?因为我没有有状态的脚手架。我们将其移至无状态类
    • 如果你想要在无状态小部件中的方法,你所要做的就是将context从build方法作为参数传递给floatingButton(context)
    • 我不确定我是否理解您关于在脚手架中添加有状态小部件作为子级的问题。你能用更多细节表达你的疑问吗?
    【解决方案3】:

    您犯了两个错误,导致您的代码无法正常工作:

    1. 您使用了错误的路由名称。将 /SecondScreen 替换为 /second
    2. 您使用了错误的上下文。仅当您的小部件具有 MaterialApp 作为其父级并且此处您使用的是 MyApp1 的上下文因此它不起作用时,您才能获取 Navigator。

    以下是供您参考的工作代码。


    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatefulWidget {
      @override
      State createState() => new MyApp1();
    }
    
    class MyApp1 extends State<MyApp> {
      List<Widget> _listSection = [];
    
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'Share IDEASS',
          initialRoute: '/',
          routes: {
            '/second': (context) => SecondScreen(),
          },
          home: AppContent(),
        );
      }
    }
    
    class AppContent extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('IDEAS'),
          ),
          body: Container(
            child: Stack(
              children: [
                floatingButton(context),
              ],
            ),
          ),
        );
      }
    
      Widget floatingButton(BuildContext context) {
        return Container(
          padding: const EdgeInsets.all(30),
          alignment: Alignment.bottomRight,
          child: FloatingActionButton(
            onPressed: () {
              Navigator.pushNamed(context, "/second");
            },
            child: Text("+"),
            backgroundColor: Colors.blue,
          ),
        );
      }
    }
    
    class SecondScreen extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("Second Route"),
          ),
          body: Center(
            child: RaisedButton(
              onPressed: () {
                Navigator.pop(context);
              },
              child: Text('Go back!'),
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 很好的解释
    • 很高兴它对您有所帮助 :)
    猜你喜欢
    • 2019-12-16
    • 1970-01-01
    • 2022-11-12
    • 2022-01-24
    • 2020-04-20
    • 1970-01-01
    • 1970-01-01
    • 2022-11-25
    • 2019-11-29
    相关资源
    最近更新 更多