当前位置:网站首页>Flutter layout Basics - page navigation and return

Flutter layout Basics - page navigation and return

2022-06-24 05:51:00 Mokong 9081

Flutter Layout basis —— Page navigation and value transfer

When it comes to navigation , The most common is something like iOS Navigation controller in push and pop effect , Again Flutter There is a similar effect in , What you use is Navigator Components .

<!--more-->

below , Take a look at Flutter in , Navigation effects Navigator.push and Navigator.pop Use .

Easy to use

The code is as follows :

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: ' Navigation Demo 1',
      home: new FirstScreen(),
    );
  }
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: AppBar(
        title: Text(' Navigation page '),
      ),
      body: Center(
          child: ElevatedButton(
        child: Text(' View the product details page '),
        onPressed: () {
          Navigator.push(context,
              new MaterialPageRoute(builder: (context) => new SecondScreen()));
        },
      )),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SecondScreen'),
      ),
      body: Center(
        child: OutlinedButton(
          child: Text(' return '),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}

Pay attention to Navigator.push when , Interface to jump to use MaterialPageRoute Included .

In code SecondScreen Added a button , The implementation method of click is Navigator.pop, For return ; But usually , No special implementation is required Navigator.pop, Because in iOS in , When using the AppBar When , The return button will be automatically added in the upper left corner ; And in Andrew , Use the system return button to return directly .

Use name navigation

Similar to route jump , Use the name instead of the class name to jump .

The following code defines three interfaces ,MyFirstPage It's the home page ,MySecondPage and MyThirdPage There are two different interfaces , There are two buttons on the home page , Corresponding to jump MySecondPage and MyThirdPage, Pass in parameters when jumping at the same time , Displayed on the corresponding page .

The code is as follows :

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyFirstPage(),
      routes: <String, WidgetBuilder>{
        '/a': (BuildContext context) => MySecondPage(title: 'Page A'),
        'b': (BuildContext context) => MyThirdPage(title: 'Page B'),
      },
    );
  }
}

class MyFirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('homepage'),
      ),
      body: Center(
        child: Column(
          children: [
            OutlinedButton(
              onPressed: () {
                Navigator.pushNamed(context, '/a');
              },
              child: new Text('PageA'),
            ),
            OutlinedButton(
              onPressed: () {
                Navigator.pushNamed(context, 'b');
              },
              child: new Text('PageB'),
            ),
          ],
        ),
      ),
    );
  }
}

class MySecondPage extends StatelessWidget {
  final String title;
  const MySecondPage({Key? key, required this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Second Page'),
      ),
      body: Center(
        child: OutlinedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: new Text(this.title),
        ),
      ),
    );
  }
}

class MyThirdPage extends StatelessWidget {
  final String? title;
  const MyThirdPage({Key? key, this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Third Page'),
      ),
      body: Center(
        child: new OutlinedButton(
            onPressed: () {
              Navigator.pop(context);
            },
            child: new Text(this.title ?? 'Default PageName')),
      ),
    );
  }
}

Here are a few points to note :

First of all routes Use , The type is <String, WidgetBuilder>, The former is the name of the page to jump and the latter is the corresponding page to jump . And the name of the jump page / It's not necessary , That is, you can define , But according to the origin of the road , It is still recommended to use uniform rules for naming .

The second is jump Navigator Use , In the previous example of direct jump , The way to do it is Navigator.push; And here we use Navigator.pushNamed.

Finally, you should pay attention to the page value transfer .

Page transfer value

Just as iOS Development , Page value transfer includes value transfer from the parent interface to the child interface and callback value transfer from the child interface to the parent interface .

Value transfer from superior page to subordinate page

The above code transfers values from the upper level page to the lower level page , but MySecondPage and MyThirdPage It's not the same , The comparison is as follows :

wecom20210730-172529.png

There are two different places : The initial declaration is different , The specific use is different ;

MySecondPage Declarative title Attribute is a non nullable String, Used required modification ( Pay attention to this place , yes required instead of @required, Some articles are not updated ), When using it, use it directly .

MyThirdPage Declarative title Property is nullable String, Not used required modification , But when it's used , Added ?? Provide default values .

If confused , You may encounter The parameter 'title' can't have a value of 'null' because of its type, but the implicit default value is 'null'. Try adding either an explicit non-'null' default value or the 'required' modifier.dart(missing_default_value_for_parameter) This kind of reporting is wrong , The reason is the difference between nullable and non nullable , The modification method is , One is to choose to declare as nullable type , Use with judgment ; One is to use required modification , Declaration cannot be empty .

Value transfer from lower level page to upper level page

Navigator.Push Methods can have return values , And the return value is Future type , When calling Navigator.Pop When the method is used , The second optional parameter passes in the content , Will be in Navigator.Push Back in .

The code is as follows :

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyFirstPage(),
      routes: <String, WidgetBuilder>{
        '/a': (BuildContext context) => MySecondPage(title: 'Page A'),
        'b': (BuildContext context) => MyThirdPage(title: 'Page B'),
      },
    );
  }
}

class MyFirstPage extends StatelessWidget {
  String callbackText = '';
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('homepage'),
      ),
      body: Center(
        child: Column(
          children: [
            OutlinedButton(
              onPressed: () {
                _pagePush(context, '/a');
              },
              child: new Text('PageA'),
            ),
            OutlinedButton(
              onPressed: () {
                // Navigator.pushNamed(context, 'b');
                _pagePush(context, 'b');
              },
              child: new Text('PageB'),
            ),
            Text(callbackText),
          ],
        ),
      ),
    );
  }
}

_pagePush(BuildContext context, String target) async {
  final result = await Navigator.pushNamed(context, target);
  ScaffoldMessenger.of(context).showSnackBar(
    new SnackBar(content: Text("$result")),
  );
}

class MySecondPage extends StatelessWidget {
  final String title;
  const MySecondPage({Key? key, required this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Second Page'),
      ),
      body: Center(
        child: OutlinedButton(
          onPressed: () {
            Navigator.pop(context, 'SecondPage Callback');
          },
          child: new Text(this.title),
        ),
      ),
    );
  }
}

class MyThirdPage extends StatelessWidget {
  final String? title;
  const MyThirdPage({Key? key, this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Third Page'),
      ),
      body: Center(
        child: new OutlinedButton(
            onPressed: () {
              Navigator.pop(context, 'ThirdPage Callback');
            },
            child: new Text(this.title ?? 'Default PageName')),
      ),
    );
  }
}

The effect is as follows :

pagecallback.gif

Note the use of the button click method above , A separate package of _pagePush Methods , And use async modification , as a result of Navigator.push The return value of Future

type , Need to use await, and await Only in async Used in decorated methods , If you have written ReactNative You should be familiar with this way of writing .

Reference resources

Navigator Dev Doc

Flutter Free video on season four - Page navigation and other

The parameter can't have a value of 'null' because of its type in Dart

Return data from the new page to the previous page

Future<T> class

原网站

版权声明
本文为[Mokong 9081]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/08/20210802153022853k.html

猜你喜欢

    随机推荐