此文章为翻译Flutter官网的Flutter for Android Developers - Intent有兴趣的小伙伴可以移步官网查看。
Intent
Flutter中的Intent是什么?
在Android中,Intent主要有两大使用方式:Activity之间的引导和模块之间的通讯。尽管Flutter没有Intent概念,你还是可以用Intent与Native交互(使用一个插件)。
Flutter中没有直接等同于Activity或Fragment的东西;而如果你想在Flutter中在页面之间引导,需要使用** Navigator和 Routes,所有都在同一个Activity中。
一个 Route是一个App的屏幕或页面的抽象, Navigator**是一个管理Route的Widget。一个Route粗略的映射一个Activity,但是它的含义不同。Navigator可以加入(Push)或者推出(Pop)Routes来从一个屏幕跳转到另一个。Navigator的工作方式像堆栈一样,你可以push()
一个新的你想加入的Route,当你想返回的时候也可以pop()
Routes。
在Android中,App的Activity需要在AndroidManifest.xml中声明。
在Flutter中,你有两个跳转页面的方法:
指定一个Route名字的Map。(MaterialApp)
直接跳转去一个Route。(WidgetApp)
下面的例子创建了一个Map:
void main() { runApp(new MaterialApp( home: new MyAppHome(), // becomes the route named '/' routes: <String, WidgetBuilder> { '/a': (BuildContext context) => new MyPage(title: 'page A'), '/b': (BuildContext context) => new MyPage(title: 'page B'), '/c': (BuildContext context) => new MyPage(title: 'page C'), }, )); }
通过push
Route的名字给Navigator
来跳转到一个Route
Navigator.of(context).pushNamed('/b');
其他Intent的流行用法是调用外部组件,例如相机或文件选择器。对于这种情况,你需要创建一个Native集成(或者用一个插件)。
如果你想学习如何制作Native集成,请查看开发 包及插件。
Flutter中如何操作外部传递的Intent?
Flutter可以操作直接告诉Android层的或请求的分享数据的Intent。
下面的例子在原生Activity上我们用Flutter代码注册了一个文字分享,所以其他App可以分享文字给我们FlutterApp。
基本流程就是我们首先要处理分享文字的数据在Android原生方(在Activity中),然后等Flutter请求使用MethodChannel提供数据。
首先注册Intent Fliter给所有的Intent在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>
然后在MainActivity中操作Intent,提取的text就是从分享的Intent中获取的,然后保存下来。当Flutter准备好处理的时候,他会用平台通道请求数据,然后从原生端发送过去。
package com.example.shared;import android.content.Intent;import android.os.Bundle;import java.nio.ByteBuffer;import io.flutter.app.FlutterActivity;import io.flutter.plugin.common.ActivityLifecycleListener;import io.flutter.plugin.common.MethodCall;import io.flutter.plugin.common.MethodChannel;import io.flutter.plugins.GeneratedPluginRegistrant;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 MethodChannel.MethodCallHandler() { @Override public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) { if (methodCall.method.contentEquals("getSharedText")) { result.success(sharedText); sharedText = null; } } }); } void handleSendText(Intent intent) { sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); } }
最后等Flutter的Widget渲染好后,从Flutter端请求数据。
import 'package:flutter/material.dart';import 'package:flutter/services.dart';void main() { runApp(new SampleApp()); }class SampleApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return new MaterialApp( title: 'Sample Shared App Handler', theme: new ThemeData( primarySwatch: Colors.blue, ), home: new SampleAppPage(), ); } }class SampleAppPage extends StatefulWidget { SampleAppPage({Key key}) : super(key: key); @override _SampleAppPageState createState() => new _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 new Scaffold(body: new Center(child: new Text(dataShared))); } getSharedText() async { var sharedData = await platform.invokeMethod("getSharedText"); if (sharedData != null) { setState(() { dataShared = sharedData; }); } } }
Flutter中的startActivityForResult()是什么?
在Flutter中Navigator类处理Route,并且通常会得到一个已经被你Push到栈中的Route的结果返回(result back)。这会通过有待 push() 在以后返回。
例如,启动一个定位Route让用户选择自己的位置,你可以做以下几点:
Map coordinates = await Navigator.of(context).pushNamed('/location');
然后,在你的定位Route中,一旦用户选择了他们的位置,你可以带着结果pop
出栈。
Navigator.of(context).pop({"lat":43.821757,"long":-79.226392});
作者:AllAboutCoding
链接:https://www.jianshu.com/p/fa65f8761b47