Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gfaraday/g_faraday

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.

AltStyle によって変換されたページ (->オリジナル) /