Skip to content

gfaraday/g_faraday

Folders and files

NameName
Last commit message
Last commit date
Jan 26, 2024
Jul 1, 2022
Jul 1, 2022
Mar 22, 2024
Jun 8, 2021
Mar 19, 2024
Jan 26, 2024
Mar 15, 2024
Jan 26, 2024
Nov 28, 2020
Sep 23, 2020
Sep 10, 2020
Mar 22, 2024
Dec 8, 2020
Nov 21, 2020
Sep 9, 2022
Sep 11, 2021
Jun 24, 2022
Sep 10, 2020
Jan 26, 2024
Mar 22, 2024

Repository files navigation

log Faraday English

Build pub_Version Flutter_Version License

一个Flutter混合栈开发解决方案

Features

  • 支持iosandroidflutter三端所有原生路由(页面切换)跳转行为
  • 支持混合栈(native -> flutter -> native)路由跳转(popTo、replace ...)
  • 支持flutter页面作为root页面
  • 支持flutter作为子页面加入原生堆栈
  • 支持flutter作为弹出页面(背景透明到native层)
  • 页面间回调传值完整支持
  • iOS导航条自动隐藏/显示
  • WillPopScope拦截滑动返回(ios)或者返回按键键(android)
  • 发送/接收全局通知
  • 支持自定义页面切换动画
  • 支持完整的生命周期监听
  • 单元测试
  • 完整的文档(7/10)

使用g_faraday的APP

序号 名称 版本号 iOS Android
0 寓小二 8.0.0 AppStore 应用宝

您的app也在使用?联系我们

Show Cases

demo

Example App

Android下载apk

设计原则

  • 对原有平台最小侵入
  • 对现有代码最小改动
  • API尽量保持和原有平台一致

更新策略

Flutter stable channel 发布后 一周内适配发布对应的g_faraday版本

Requirements

  • Flutter 3.0.5 • channel stable
  • iOS 10.0+ Xcode 12.0+ Swift 5.1+
  • Android minSdkVersion 16 Kotlin 1.4.10+

版本对应关系

g_faraday flutter cocoapods remark
^1.0.0 Flutter 3.0.5 • channel stable • https://github.com/flutter/flutter.git any recommend
^1.0.0-beta.1 Flutter 3.0.3 • channel stable • https://github.com/flutter/flutter.git any not recommend
^0.7.2 Flutter 2.5.0 • channel stable • https://github.com/flutter/flutter.git any not recommend
^0.7.0 Flutter 2.0.0 • channel stable any not recommend
^0.5.1-nullsafety.0 Flutter 1.24.0-10.2.pre • channel beta any not recommend
^0.5.0-nullsafety.0 Flutter 1.24.0-10.2.pre • channel beta any not recommend
^0.4.0 Flutter 1.24.0-10.2.pre • channel beta any not recommend

快速开始

如果您已经有其他类似框架使用经验,可以直接查看Example浏览最佳实践。

run example project: flutter run --no-sound-null-safety

添加依赖

dependencies:
  g_faraday: ^0.7.0

Flutter 端集成

flutter侧的集成工作,主要是注册需要从原生打开的页面。

// 0x00 定义 route
final route = faraday.wrapper((settings) {
    switch (settings.name) {
    case 'first_page':
        return CupertinoPageRoute(builder: (context) => Text('First Page'));
    case 'second_page':
        return CupertinoPageRoute(builder: (context) => Text('Second Page'));
    }
    return CupertinoPageRoute(builder: (context) => Text(settings.name));
});

// 0x01 将 route 赋给你的app widget
CupertinoApp(onGenerateRoute: (_) => route);

// 0x02 flutter 侧集成完毕,接下来你可以选择 集成iOS/Android

注意不管是CupertinoApp还是MaterialApp都不要设置home

iOS 集成

Objective-C集成看这里

为了实现从Flutter端打开原生页面的应用场景,所以我们需要实现一个打开原生页面的protocol

// 0x00 实现 `FaradayNavigationDelegate`
extension AppDelegate: FaradayNavigationDelegate {

    func push(_ name: String, arguments: Any?, options: [String : Any]?, callback token: CallbackToken) {

        let isFlutter = options?["flutter"] as? Bool ?? false
        let isPresent = options?["present"] as? Bool ?? false

        let vc = isFlutter ? FaradayFlutterViewController(name, arguments: arguments) : FirstViewController(name, arguments: arguments)

        let topMost = UIViewController.fa.topMost
        if (isPresent) {
            // 此处注意
            // vc.modalPresentationStyle 不能是`pageSheet`
            // 如果的确需要这种UI效果,可以配合透明背景,在Flutter侧实现
            topMost?.present(vc, animated: true, completion: nil)
        } else {
            topMost?.navigationController?.pushViewController(vc, animated: true)
        }

        // 非常重要
        // 如果此处不调用 `enableCallback` 那么flutter侧`await Navigator`则永远不会返回
        vc.fa.enableCallback(with: token)
    }
}

// 0x01 在 `application: didFinishLaunchingWithOptions`中启动flutter engine
Faraday.default.startFlutterEngine(navigatorDelegate: self)


// 0x02 打开一个flutter 页面
let vc = FaradayFlutterViewController("first_page", arguments: nil)
navigationController?.pushViewController(vc, animated: true)

// 0x03 集成完毕

Android 集成

为了实现从Flutter端打开原生页面的应用场景,所以我们需要实现一组打开原生页面的接口

// 0x00 实现 navigator
class SimpleFlutterNavigator : FaradayNavigator {

    companion object {
        const val KEY_ARGS = "_args"
    }

    override fun create(name: String, arguments: Serializable?, options: HashMap<String, *>?): Intent? {
        val context = Faraday.getCurrentActivity() ?: return null

        val isFlutterRoute = options?.get("flutter") == true

        if (isFlutterRoute) {
            // singleTask 模式
            val builder = FaradayActivity.builder(name, arguments)

            // 你看到的绿色的闪屏就是这个
            builder.backgroundColor = Color.WHITE
            builder.activityClass = SingleTaskFlutterActivity::class.java

            return builder.build(context);
        }

        when (name) {
            "flutter2native" -> {
                return Intent(context, FlutterToNativeActivity::class.java)
            }
            "native2flutter" -> {
                return Intent(context, Native2FlutterActivity::class.java)
            }
            "tabContainer" -> {
                return Intent(context, TabContainerActivity::class.java)
            }
            else -> {
                val intent = Intent(Intent.ACTION_VIEW)
                intent.data = Uri.parse(name)
                intent.putExtra(KEY_ARGS, arguments)
                return intent
            }
        }

    }

    override fun pop(result: Serializable?) {
        val activity = Faraday.getCurrentActivity() ?: return
        if (result != null) {
            activity.setResult(Activity.RESULT_OK, Intent().apply { putExtra(KEY_ARGS, result) })
        }
        activity.finish()
    }

    override fun enableSwipeBack(enable: Boolean) {

    }

}

// 0x01 在 Application 的onCreate方法中启动FlutterEngine
if (!Faraday.startFlutterEngine(this, SimpleFlutterNavigator())) {
    GeneratedPluginRegistrant.registerWith(Faraday.engine)
}

// 0x02 打开一个Flutter页面
val intent = FaradayActivity.build(context, routeName, params)
context.startActivity(intent)

faraday 全家桶 (推荐)

在进行Flutter混合开发时会遇到很多相似的问题,我们提供了相应的解决方案大家玩的开心。

FAQ

是否支持使用第三方路由框架?

支持。

example中提供了flurogetx的实现范例

是否支持使用url配置路由?

支持。

可以保证3端统一使用url进行路由管理。

打包时提示 failed to load module 'g_faraday'

请使用xcode 12.3及以上版本

Communication

扫码加入微信群,请备注 faraday

wechat group

Contributing

If you wish to contribute a change to any of the existing plugins in this repo, please review our contribution guide and open a pull request.

License

g_faraday is released under the MIT license. See LICENSE for details.