Flutter 中的Intents

2018-12-21  本文已影响0人  Asbefore如初_3142

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") 传递而来。

上一篇下一篇

猜你喜欢

热点阅读