This is the 12th day of my participation in Gwen Challenge

Weex is dedicated to enabling developers to build Android, iOS and Web applications based on common cross-platform Web development languages and development experience. As mentioned by Ali Center, the future trend of front-end is mobile terminal. As a cross-terminal solution divided by RN and Flutter, it is particularly important to study Weex deeply.

preface

Most applications have multiple pages or views and want to smoothly transition users from one page to another. The routing and navigation features of Flutter help you manage naming and transitions between screens in your application.

There are two core concepts and classes for managing multiple pages: Route and Navigator. A route is an abstraction of a screen or page, and a Navigator is the Widget that manages the route. The Navigator can jump from page to page with a route on and off the stack.

The Navigator inherits from StatefulWidget, which is also a widget. It has a number of related static functions to help us navigate to pages and interact with data:

● Push the router information set to Navigator to realize page hopping.

● Of is mainly to get the good state of the most recent instance of Navigator.

● Pop to navigate to a new page or return to the previous page.

● canPop determines if you can navigate to a new page

● maybePop may navigate to new pages

● popAndPushNamed specifies a routing path and navigates to the new page.

● popUntil Pop is repeated until the parameters of the function return true.

● pushAndRemoveUntil pushes the given route to the Navigator, deleting the previous route until the predicate returns true.

● pushNamed pushes the named route to the Navigator.

● pushNamedAndRemoveUntil pushes the named route to the Navigator, deleting the previous route until the predicate returns true.

● pushReplacement Indicates route replacement.

● pushReplacementNamed This is also a replacement route operation. Push a named route to the Navigator and process the previous route after the new route completes the animation.

● removeRoute Deletes the Route from the Navigator and executes the route. dispose operation.

● removeRouteBelow Removes the Route from the Navigator and executes the route. dispose operation to replace the Route from the anchorRouter passed in.

● Replace Replaces the route in the Navigator with a new route.

● replaceRouteBelow replaces the route in the Navigator with a new route that was passed into the anchorRouter parameter.

1. Route management

To switch screens in Flutter, we can access the route to draw the new Widget. There are two core concepts and classes for managing multiple screens: Route and Navigator. A Route is an abstraction of an application’s “screen” or “page” (think of it as an Activity), and a Navigator is a Widget that manages the Route. The Navigator can switch pages using push and pop routes. In RN, you can use react- Navigation to navigate between pages. Flutter has a similar implementation using Navigator and Routes. A route is an abstraction of a “screen” or “page” in an App, and a Navigator is a widget that manages multiple routes. You can roughly map a route to a UIViewController. Navigator works much like the UINavigationController in iOS, pushing () and pop() routes when you want to jump to or return to a new page. There are two main widgets in Flutter for navigating between pages:

  • A Route is an application abstraction of a screen or page;

  • The Navigator is a widget that manages routes;

There are two options for implementing page navigation in the Flutter:

  • Specify a Map consisting of route names. (MaterialApp)

  • Jump to a route directly. (WidgetApp)

void main() {
  runApp(MaterialApp(
    home: MyAppHome(), // becomes the route named '/'
    routes: <String, WidgetBuilder> {
      '/a': (BuildContext context) => MyPage(title: 'page A'),
      '/b': (BuildContext context) => MyPage(title: 'page B'),
      '/c': (BuildContext context) => MyPage(title: 'page C'),})); }Copy the code

Jump by pushing the name of the route to a Navigator:

Navigator.of(context).pushNamed('/b');
Copy the code

You can also use the Navigator’s push method, which adds the given route to the Navigator’s history. In the following example, the MaterialPageRoute widget is a template route that ADAPTS the entire page based on the platform. In the following example, the widget is a template route that uses platform adaptation to replace the entire page. It requires a WidgetBuilder as a required parameter.

Navigator.push(context, MaterialPageRoute(builder: (BuildContext context)
 => UsualNavscreen()));
Copy the code

Two, route jump and value transmission

The default navigation in Flutter is divided into two types: named routes and constructed routes.

2.1 Named Routes

This route needs to be defined at the beginning now when you create your App

new MaterialApp(
      ....
      routes: {
        "nameRoute":(BuildContext context)=>new SecondPage(),
      },
    );
Copy the code

You can then jump in the program using navigator.pushnamed

Navigator.pushNamed(context, "nameRoute");
Copy the code

The disadvantage of this route is that parameters cannot be passed.

2.2 Route Construction

Use custom methods to build a route during push

Navigator.push(context, new MaterialPageRoute(builder: (BuildContext context){
   return new ThirdPage(title:"Please enter a nickname");
}))
Copy the code

This way you can pass parameters.

2.3 Return to the previous page with parameters

Use the Navigator’s POP return to return to the previous level and carry a parameter

Navigator.pop(context,"Carrying parameters");
Copy the code

2.4 Parameters returned by receiving routes

Note that the methods of the push series return a Future that can be used to receive arguments

 Navigator.pushNamed<String>(context, "nameRoute").then( (String value){
   // Process the code
});


 Navigator.push<String>(context, new MaterialPageRoute(builder: (BuildContext context){

    return new ThirdPage(title:"Please enter a nickname");

  })).then( (String result){

       // Process the code

  });
Copy the code

Note that dart uses generics with a < generic parameter >, as opposed to Java Kotlin. Simply put, since Android has startActivityForResult to get the result returned after a jump, the Navigator class in Flutter is used not only to process the route in the Flutter, but also to get the result returned by the route you just pushed onto the stack. This is achieved by await the result of the route return. For example, to jump to the location route and let the user select a location, you might do something like this:

Map coordinates = await Navigator.of(context).pushNamed('/location');
Copy the code

Then, in the location route, once the user has selected the location, the result is popped () off the stack:

Navigator.of(context).pop({"lat":43.821757."long":79.226392});
Copy the code

Three, external application value transfer

Flutter can handle Intents from Android by communicating directly with the Android layer and requesting shared data. In this example, we register a text-sharing Intent, So other applications can share text to our Flutter application. The basic flow of the Flutter application is that we first process shared text data on the Android side, then wait for the Flutter request data, and then send it via MethodChannel. First register the Intent we want to handle in androidmanifest.xml:

<activity
  android:name=".MainActivity"
  android:launchMode="singleTop"
  android:theme="@style/LaunchTheme"
  android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
  android:hardwareAccelerated="true"
  android:windowSoftInputMode="adjustResize"> <! -... --> <intent-filter> <action android:name="android.intent.action.SEND" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="text/plain" />
  </intent-filter>
</activity>
Copy the code

Then, in MainActivity, you can handle the intent, and once we get the shared text data from the intent, we hold it until the Flutter requests it when it’s done and ready.

public class MainActivity extends FlutterActivity {

  private String sharedText;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);
    Intent intent = getIntent();
    String action = intent.getAction();
    String type = intent.getType();

    if(Intent.ACTION_SEND.equals(action) && type ! =null) {
      if ("text/plain".equals(type)) {
        handleSendText(intent); // Handle text being sent}}new MethodChannel(getFlutterView(), "app.channel.shared.data").setMethodCallHandler(
      new MethodCallHandler() {
        @Override
        public void onMethodCall(MethodCall call, MethodChannel.Result result) {
          if (call.method.contentEquals("getSharedText")) {
            result.success(sharedText);
            sharedText = null; }}}); }voidhandleSendText(Intent intent) { sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); }}Copy the code

Finally, in Flutter, you can request data when rendering a Flutter view.

class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);

  @override
  _SampleAppPageState createState() => _SampleAppPageState();
}

class _SampleAppPageState extends State<SampleAppPage> {
  static const platform = const MethodChannel('app.channel.shared.data');
  String dataShared = "No data";

  @override
  void initState() {
    super.initState();
    getSharedText();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(body: Center(child: Text(dataShared)));
  }

  getSharedText() async {
    var sharedData = await platform.invokeMethod("getSharedText");
    if(sharedData ! =null) { setState(() { dataShared = sharedData; }); }}}Copy the code

Jump to other applications

In iOS, to jump to another App, you need a specific URL Scheme. For system-level apps, this scheme depends on the App. To implement this functionality in Flutter, you can create a native platform integration layer or use an existing plugin, such as URl_launcher. The process is as follows: If the Flutter is running after the installation process:

export LANG=en_US.UTF- 8 - 
Error running pod install
Copy the code

You need to add the following to profile.bash_profile:

export LANG=en_US.UTF- 8 -
Copy the code

Download the url_launcher plugin from the Flutter developer website and add a dependency to the pubspec.yaml file:

dependencies:
    url_launcher: ^5.03.
Copy the code

Installation:

flutter pub get
Copy the code

Import:

import 'package:url_launcher/url_launcher.dart';
Copy the code

Use:

① Open a browser

_launchURL and _openMapApp are user-defined method names. You can customize the method names based on your own scenarios:

_launchURL() async {
     const url = 'https://flutter.io';
     if (await canLaunch(url)) {
          await launch(url);
     } else {
          throw 'Could not launch $url'; }}Copy the code

② Open the external APP

To open the external APP, the external APP needs to provide the schema for the jump. The URL defined in this method is app-scheme-URL. Android and IOS urls are different, so it is judged separately.

 _openMapApp() async {
     const url = 'geo: 52.32, 4.917'; // The schema provided by APP
     if (await canLaunch(url)) {
          await (launch(url)); // Open it in android
     } else {
          / / open the iOS
          const url = 'http://maps.apple.com/?ll=52.32, 4.917';
          if (await canLaunch(url)) {
            await launch(url);
          } else {
            throw 'Could not launch $url'; }}}Copy the code