Flutter中的Intent等价于什么?
在Android中,对于Intent有两个最主要用例:在Activity之间导航,以及与组件通信。另一个方面,Flutter没有Intent的概念,尽管您仍然可以通过通过native调用Intent。
Flutter并没有直接等同于Activity和Fragment;相反,在Flutter中,您可以使用Navigator和Route在屏幕之间导航,所有这些都在同一个Activity。
Route是应用程序“屏幕”或“页面”的抽象,而Navigator是管理路由的小部件。路线大致映射到Activity,但它不具有相同的含义。Navigator的工作方式就像一个堆栈,您可以用push()导航要导航到新路线,也可以在用pop()“返回”。
在Android中,您在AndroidManifest.xml定义activity。
在Flutter中,您有几个选项可以在页面之间导航:
- 置顶一个
Map路由名称。(使用MaterialApp) - 直接导航到路线。(使用
WidgetsApp)
下面例子构建一个Map
void main() {
runApp(MaterialApp(
home: const MyAppHome(), // Becomes the route named `/`
routes: <String, WidgetBuilder>{
'/a': (context) => const MyPage(title: 'page A'),
'/b': (context) => const MyPage(title: 'page B'),
'/c': (context) => consr MyPage(title: 'page C'),
},
));
}
通过push将其名称添加到Navigator
Navigator.of(context).pushNamed('/b');
另一个使用Intent调用外部组件,例如调用相机或文件选择器。为此,你需要创建原生平台集成(或使用现有插件)。
要了解如何构建原生平台集成,请参阅开发包和插件。
如何在Flutter中处理来自外部应用程序的传入Intent
Flutter可以通过直接与Android层对话并请求共享数据来处理来自Android传入的Intent。
以下示例在运行我们的Flutter代码的,在Activity上注册了一个文本共享Intent filter,因此其他应用程序可以与我们的Flutter应用程序共享文本。
基本流程意味着我们首先在Android端处理共享文本数据(在Activity的MethodChannel)
首先,在AndroidManifest.xml注册intent filter
<activity
android:name=".MainActivity"
android:launchMode="@style/LaunchTheme"
abdroid:confirChanges="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,从Intent中提取共享文本并保存它。当Flutter准备好处理时,它使用platform channel,并从native端发送:
package com.example.shared;
import android.content.Intent;
impoort android.os.Bundle;
import androidx.annotation.NonNull;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity {
private String sharedText;
private static final String CHANNEL = "app.channel.shared.data";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
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
}
}
}
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result) -> {
if (call.method.contentEquals("getSharedText") {
result.success(sharedText);
sharedText = null;
}
}
);
}
void handleSendText(Intent intent) {
sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
}
}
最后,在widget渲染时向Flutter端请求数据:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(const SampleApp());
}
class SampleApp extends StatelessWidget {
const SampleApp({Key? key}) : super(key: key);
// This widget is the root of your appliation.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Sample Shared App Handler',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const SampleAppPage(),
);
}
}
class SampleAppPage extends StatefulWidget {
const SampleAppPage({Key? key}) : super(key: key);
@override
State<SampleAppPage> createState() => _SampleAppPageState();
}
class _SampleAppPageState extends State<SampleAppPage> {
static const platform = MethodChannel('app.channel.shared.data');
String dataShared = 'No data';
@override
void initState() {
supter.initState();
getSHaredText();
}
@override
Widget build(BuildContext context) {
return Scaffold(body: Center(child: Text(dataShared)));
}
Future<void> getSharedText() async {
var sharedData = await platform.invokeMethod('getSharedText');
if (sharedData != null) {
setState(() {
dataShared = sharedData;
});
}
}
}
startActivityForResult()的等价物是什么?
该类Navigator处理Flutter中的路由,并用于从您已经push到对战的路由中获取结果。这是通过await Future push()的返回值。
例如,要启动一个位置路由让用户选择他们的为智慧,你可以执行以下操作:
Object? coordinates = await Navigator.of(context).pushNamed('/location');
然后,在您的位置路线中,一旦用户选择了他们的位置,你就可以pop讲结果返回来。
Navigator.of(context).pop({'lat': 43.821757, 'long': -79.226392});