美文网首页
Flutter 中的Intents

Flutter 中的Intents

作者: Asbefore如初_3142 | 来源:发表于2018-12-21 15:25 被阅读0次

    Flutter 中的 Intents

    可以看看这篇 Flutter 页面跳转,携带参数的页面跳转的使用和说明点击跳转

    在Android中,Intent 用来做Activity 之间的跳转,又或者用来发送广播,传递消息。那么,在Flutter中,它有什么替代方式呢?

    如果需要在Flutter中进行页面切换,可以使用路由,具体代码如下:

    import 'package:flutter/material.dart';
    
    //void main() => runApp(MaterialApp(home: DemoApp()));
    
    void main() {
      runApp(MaterialApp(
        home: DemoApp(), // 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'),
        },
      ));
    }
    
    class MyPage extends StatelessWidget {
      final String title;
    
      MyPage({this.title});
    
      Widget build(BuildContext context) {
        return Center(child: Text(title));
      }
    }
    
    class DemoApp extends StatelessWidget {
    //  Widget build(BuildContext context) => Scaffold(body: Signature());
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Text("DemoApp"),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () => _toPageA(context),
            tooltip: 'Update Text',
            child: Icon(Icons.update),
          ),
        );
      }
    
      void _toPageA(BuildContext context) {
        Navigator.of(context).pushNamed("/a");
      }
    }
    
    

    首先自定义了 routes 然后定义了按钮点击事件,使其跳转到 pageA

    routes 定义多个页面并省略 home 的写法

    在 Flutter中,编写一个页面,必须提供 homereturn 一个 Widght 来显示页面,但是在 MaterialApp 中,通过编写 routes 是可以忽略掉 home 的,就像下面的例子:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(new FlutterReduxApp());
    }
    
    class FlutterReduxApp extends StatelessWidget {
      FlutterReduxApp({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(routes: {
          "/": (context) {
    //                store.state.platformLocale = Localizations.localeOf(context);
            return MyPage();
          },
          "/b": (context) {
            ///通过 Localizations.override 包裹一层,
            return MyPage();
          },
          "/c": (context) {
            return MyPage();
          },
        });
      }
    }
    
    class MyPage extends StatelessWidget {
      final String title;
    
      MyPage({this.title});
    
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(title: new Text("this is Push Page")),
          body: new Center(
            child: new RaisedButton(
              child: new Text("点击返回"),
              onPressed: () => Navigator.of(context).pop("this is result text"),
              color: Colors.blue,
              highlightColor: Colors.lightBlue,
            ),
          ),
        );
      }
    }
    
    

    在routes 中,必须提供 / 这样的一个根目录,否则是会报错的,就像这样

    class FlutterReduxApp extends StatelessWidget {
      FlutterReduxApp({Key key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(routes: {
          "/a": (context) {
    //                store.state.platformLocale = Localizations.localeOf(context);
            return MyPage();
          },
          "/b": (context) {
            ///通过 Localizations.override 包裹一层,
            return MyPage();
          },
          "/c": (context) {
            return MyPage();
          },
        });
      }
    }
    

    错误:

    I/flutter (20735): 'package:flutter/src/widgets/app.dart': Failed assertion: line 178 pos 10: 'builder != null ||
    I/flutter (20735):          home != null ||
    I/flutter (20735):          routes.containsKey(Navigator.defaultRouteName) ||
    I/flutter (20735):          onGenerateRoute != null ||
    I/flutter (20735):          onUnknownRoute != null'
    

    Flutter中如何在dart 和 java 文件之间传递数据?

    某些数据需要在java端处理之后,交由界面显示,这时候就需要flutter 和java 之间的交互了

    首先,在 java 文件ActivityonCreate 中定义如下方法:

    
    package com.example.fluttertestapp;
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.widget.Toast;
    
    import io.flutter.app.FlutterActivity;
    import io.flutter.plugin.common.MethodCall;
    import io.flutter.plugin.common.MethodChannel;
    import io.flutter.plugins.GeneratedPluginRegistrant;
    
    public class MainActivity extends FlutterActivity {
    
        private final String sharedText = "this is shared text";
        Handler handler;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            GeneratedPluginRegistrant.registerWith(this);
            handler = new Handler();
    //        handler.postDelayed(new Runnable() {
    //            @Override
    //            public void run() {
    //
    //                Toast.makeText(MainActivity.this, String.format("start main thread:%d", 1600), Toast.LENGTH_SHORT).show();
    //            }
    //        }, 1600);
            new MethodChannel(getFlutterView(), "app.channel.shared.data")
                    .setMethodCallHandler(new MethodChannel.MethodCallHandler() {
                        @Override
                        public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
                            if (methodCall.method.contentEquals("getSharedText")) {
                                result.success(sharedText);
                            }
                        }
                    });
    
        }
    }
    
    

    然后在 main.dart 中定义

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    void main() {
      runApp(SampleApp());
    }
    
    class SampleApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Sample Shared App Handler',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: SampleAppPage(),
        );
      }
    }
    
    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;
          });
        }
      }
    }
    
    

    运行程序就可正确的获取到 shareText

    在看官方demo中,发现了await 字眼,说明应该是延时调用,所以,尝试在 activity 中也延时返回数据,发现,并不会导致程序阻塞,但是会导致数据获取失败,在实际测试中,当延迟在 1600 的时候,有时成功获取 shareText ,有时则失败。具体代码如下:

    package com.example.fluttertestapp;
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.widget.Toast;
    
    import io.flutter.app.FlutterActivity;
    import io.flutter.plugin.common.MethodCall;
    import io.flutter.plugin.common.MethodChannel;
    import io.flutter.plugins.GeneratedPluginRegistrant;
    
    public class MainActivity extends FlutterActivity {
    
        private final String sharedText = "this is shared text";
        Handler handler;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            GeneratedPluginRegistrant.registerWith(this);
            handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    new MethodChannel(getFlutterView(), "app.channel.shared.data")
                            .setMethodCallHandler(new MethodChannel.MethodCallHandler() {
                                @Override
                                public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
                                    if (methodCall.method.contentEquals("getSharedText")) {
                                        result.success(sharedText);
                                    }
                                }
                            });
    
                    Toast.makeText(MainActivity.this, String.format("start main thread:%d", 1600), Toast.LENGTH_SHORT).show();
                }
            }, 1600);
    
        }
    }
    
    

    为了防止调用方法的失败,最好不要在主线程中执行延时线程去返回方法。

    Flutter 中如何跳转到另一个页面后,获取返回值?

    在Android原生编程中,可以使用 startActivityForResult 来获取另一个页面的返回值,那么,在Flutter 中呢

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MaterialApp(
        home: DemoApp(), // becomes the route named '/'
        routes: <String, WidgetBuilder>{
          '/a': (BuildContext context) {
            debugPrint("select route A");
    //        Navigator.of(context).pop("this is result text");
            return MyPage(title: "page A");
          }
        },
      ));
    }
    
    class MyPage extends StatelessWidget {
      final String title;
    
      MyPage({this.title});
    
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(title: new Text("this is Push Page")),
          body: new Center(
            child: new RaisedButton(
              child: new Text("点击返回"),
              onPressed: () => Navigator.of(context).pop("this is result text"),
              color: Colors.blue,
              highlightColor: Colors.lightBlue,
            ),
          ),
        );
      }
    }
    
    class DemoApp extends StatelessWidget {
    //  Widget build(BuildContext context) => Scaffold(body: Signature());
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Text("DemoApp"),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () => _toPageA(context),
            tooltip: 'Update Text',
            child: Icon(Icons.update),
          ),
        );
      }
    
      Future _toPageA(BuildContext context) {
        debugPrint("this is debug info");
    //    Navigator.of(context).pushNamed("/a");
        Future result = Navigator.of(context).pushNamed("/a");
        result.then((value) {
          debugPrint(value);
        });
      }
    }
    
    

    首先,通过 Navigator.of(context).pushNamed("/a") 跳转到另一个页面,然后使用 Future.then 获取返回,这个返回值是在另一个页面中,通过Navigator.of(context).pop("this is result text") 传递而来。

    相关文章

      网友评论

          本文标题:Flutter 中的Intents

          本文链接:https://www.haomeiwen.com/subject/ckojkqtx.html