Flutter-Android开发者文档 -Intent

作者: AllAboutCoding | 来源:发表于2018-06-26 00:39 被阅读125次

    此文章为翻译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'),
        },
      ));
    }
    

    通过pushRoute的名字给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


    AllAboutCoding

    相关文章

      网友评论

      本文标题:Flutter-Android开发者文档 -Intent

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