【问题标题】:Switching pages in flutter在颤动中切换页面
【发布时间】:2019-12-31 05:44:58
【问题描述】:

我有一个使用抽屉小部件创建的侧边菜单,我想在侧边菜单中的页面之间导航。我正在使用 Navigator.push() 这样做,但由于某种原因,页面不会改变。

这些项目出现在侧边菜单中,但单击时,页面保持不变。有谁知道我是如何滥用 Navigator.push() 的?

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override 
  Widget build(BuildContext context){
    return MaterialApp(
      title: 'Grid App',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Grip App'),
        ),
        body: Center(
          child: Text('Hello, this is the start page!'),
        ),
        drawer: Drawer(
          child: ListView(
            children: <Widget>[
              DrawerHeader(
                child: Text("Navigation"),
                decoration: BoxDecoration(
                color: Colors.grey[700]
                ),
              ),
              ListTile(
                title: Text("First Page"),
                onTap: (){
                  Navigator.push(
                    context, 
                    MaterialPageRoute(builder: (context) => FirstPage()),);
                },
              ),
              ListTile(
                title: new Text("Second Page"),
                onTap: () {
                  Navigator.push(context,
                    new MaterialPageRoute(builder: (context) => new SecondPage()),);
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class FirstPage extends StatelessWidget{
  @override 
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(
        title: Text("First Page"),
      ),
        body: Center(
          child: Text("You're on the first page!"),
        ),
    );
  }
}

class SecondPage extends StatelessWidget{
  @override 
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Page"),
      ),
        body: Text("This is the second page"),
    );
  }
}

【问题讨论】:

    标签: flutter


    【解决方案1】:

    只需将 MaterialApp 与另一个屏幕分开即可。只需右键单击 Scaffold 小部件并选择 Extract Widget。为您的小部件命名,它会将您的代码提取到另一个无状态小部件中。

    将此代码复制粘贴到dartpad 并运行它

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override 
      Widget build(BuildContext context){
        return MaterialApp(
          title: 'Grid App',
          home: NewApp(),
        );
      }
    }
    
    class NewApp extends StatelessWidget {
      const NewApp({
        Key key,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Grip App'),
          ),
          body: Center(
            child: Text('Hello, this is the start page!'),
          ),
          drawer: Drawer(
            child: ListView(
              children: <Widget>[
                DrawerHeader(
                  child: Text("Navigation"),
                  decoration: BoxDecoration(
                  color: Colors.grey[700]
                  ),
                ),
                ListTile(
                  title: Text("First Page"),
                  onTap: (){
                    Navigator.push(
                      context, 
                      MaterialPageRoute(builder: (context) => FirstPage()),);
                  },
                ),
                ListTile(
                  title: new Text("Second Page"),
                  onTap: () {
                    Navigator.push(context,
                      new MaterialPageRoute(builder: (context) => new SecondPage()),);
                  },
                ),
              ],
            ),
          ),
        );
      }
    }
    
    class FirstPage extends StatelessWidget{
      @override 
      Widget build(BuildContext context){
        return Scaffold(
          appBar: AppBar(
            title: Text("First Page"),
          ),
            body: Center(
              child: Text("You're on the first page!"),
            ),
        );
      }
    }
    
    class SecondPage extends StatelessWidget{
      @override 
      Widget build(BuildContext context){
        return Scaffold(
          appBar: AppBar(
            title: Text("Second Page"),
          ),
            body: Text("This is the second page"),
        );
      }
    }
    

    【讨论】:

      【解决方案2】:

      如果您像正在使用的那样在 MateriaApp 上下文中进行操作,则导航器将无法工作。将 MaterialApp 小部件移除到 main() 或为此制作另一个小部件。

      试试这个:

      
      import 'package:flutter/material.dart';
      import 'package:flutter/rendering.dart';
      
      void main() => runApp(MaterialApp(
        home: MyApp(),
      ));
      
      class MyApp extends StatelessWidget {
        @override 
        Widget build(BuildContext context){
          return Scaffold(
              appBar: AppBar(
                title: Text('Grip App'),
              ),
              body: Center(
                child: Text('Hello, this is the start page!'),
              ),
              drawer: Drawer(
                child: ListView(
                  children: <Widget>[
                    DrawerHeader(
                      child: Text("Navigation"),
                      decoration: BoxDecoration(
                      color: Colors.grey[700]
                      ),
                    ),
                    ListTile(
                      title: Text("First Page"),
                      onTap: (){
                        Navigator.push(
                          context, 
                          MaterialPageRoute(builder: (context) => FirstPage()),);
                      },
                    ),
                    ListTile(
                      title: new Text("Second Page"),
                      onTap: () {
                        Navigator.push(context,
                          new MaterialPageRoute(builder: (context) => new SecondPage()),);
                      },
                    ),
                  ],
                ),
              ),
          );
        }
      }
      
      class FirstPage extends StatelessWidget{
        @override 
        Widget build(BuildContext context){
          return Scaffold(
            appBar: AppBar(
              title: Text("First Page"),
            ),
              body: Center(
                child: Text("You're on the first page!"),
              ),
          );
        }
      }
      
      class SecondPage extends StatelessWidget{
        @override 
        Widget build(BuildContext context){
          return Scaffold(
            appBar: AppBar(
              title: Text("Second Page"),
            ),
              body: Text("This is the second page"),
          );
        }
      }
      

      【讨论】:

        【解决方案3】:

        这里的大问题是使用了错误的上下文。

        您不能将应用程序上下文用于 Navigator。试试Builder

        class MyApp extends StatelessWidget {
          @override
          Widget build(BuildContext context) {
            return MaterialApp(
              title: 'Grid App',
              home: Builder(
                builder: (context) => buildScaffold(context),
              ),
            );
          }
        
          Scaffold buildScaffold(BuildContext context) {
            return Scaffold(
              appBar: AppBar(
                title: Text('Grip App'),
              ),
              body: Center(
                child: Text('Hello, this is the start page!'),
              ),
              drawer: Drawer(
                child: ListView(
                  children: <Widget>[
                    DrawerHeader(
                      child: Text("Navigation"),
                      decoration: BoxDecoration(color: Colors.grey[700]),
                    ),
                    ListTile(
                      title: Text("First Page"),
                      onTap: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(builder: (context) => FirstPage()),
                        );
                      },
                    ),
                    ListTile(
                      title: new Text("Second Page"),
                      onTap: () {
                        Navigator.push(
                          context,
                          new MaterialPageRoute(builder: (context) => new SecondPage()),
                        );
                      },
                    ),
                  ],
                ),
              ),
            );
          }
        }
        

        【讨论】:

          【解决方案4】:

          快速修复

          void main() => runApp(MaterialApp(home: MyApp()));
          

          您面临的错误

          您当前的代码给出以下错误,您也可以在控制台中看到该错误

          错误:处理手势时抛出以下断言: 使用不包含 Navigator 的上下文请求的 Navigator 操作。 用于从 Navigator 推送或弹出路由的上下文必须是作为 Navigator 小部件后代的小部件的上下文。


          您可以通过 MaterialAppBuilder 解决此问题

          【讨论】:

            猜你喜欢
            • 2020-02-18
            • 2018-12-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-12-21
            • 1970-01-01
            • 2019-01-16
            相关资源
            最近更新 更多