titanflutter 1.0.4 titanflutter: ^1.0.4 copied to clipboard
A next-generation Flutter-Native hybrid solution. TitanFlutter is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts.
TitanFlutter #
A next-generation Flutter-Native hybrid solution. TitanFlutter is a Flutter plugin which enables hybrid integration of Flutter for your existing native apps with minimum efforts.The philosophy of TitanFlutter is to use Flutter as easy as using a WebView. Managing Native pages and Flutter pages at the same time is non-trivial in an existing App. TitanFlutter takes care of page resolution for you. The only thing you need to care about is the name of the page(usually could be an URL).
Prerequisites #
You need to add Flutter to your project before moving on.
Getting Started #
Add a dependency in you Android project. #
-
open you root project and edit gradle.property // titanflutter TITANFLUTTER_VERSION=1.0.4 titanflutterModule=aar
-
open you root project and edit app/build.gradle // titanflutter if (titanflutterModule.equals("aar")) { compile "com.meiyou:titanflutter:${TITANFLUTTER_VERSION}" } else { compile project(":titanflutter") }
-
open you root project and edit app/build.gradle, you need add config like this, otherwise you will get :More than one file was found with OS independent path 'lib/armeabi-v7a/libflutter.so' compile error
packagingOptions { pickFirst 'lib/x86/libflutter.so' pickFirst 'lib/armeabi-v7a/libflutter.so' pickFirst 'lib/arm64-v8a/libflutter.so' pickFirst 'lib/armeabi/libflutter.so' }
-
when your android project Application Not extends FlutterApplication, you will got a crash like :Caused by: java.lang.IllegalStateException: ensureInitializationComplete must be called after startInitialization : 4.1:let your Android project Application extends FlutterApplication,it is a suggestion。 4.2:if you do not use first case,you need to make your MainActivity onCreate method write FlutterMain.startInitialization(getApplicationContext()); before super.onCreate() method: finally add follow code in your MainActivity onCreate() method: TitanFlutterPlugin.init(new IPlatform() { @Override public Application getApplication() { return MainActivity.this.getApplication(); }
/** * 获取应用入口的Activity,这个Activity在应用交互期间应该是一直在栈底的 * @return */ @Override public Activity getMainActivity() { if (MainActivity.sRef != null) { return MainActivity.sRef.get(); } return null; } @Override public boolean isDebug() { return true; } /** * 如果flutter想打开一个本地页面,将会回调这个方法,页面参数将会拼接在url中 * * 例如:sample://nativePage?aaa=bbb * * 参数就是类似 aaa=bbb 这样的键值对 * * @param context * @param url * @param requestCode * @return */ @Override public boolean startActivity(Context context, String url, int requestCode) { Debuger.log("startActivity url="+url); return PageRouter.openPageByUrl(context,url,requestCode); } @Override public Map getSettings() { return null; } });
Add a dependency in you Flutter project. #
Open you pubspec.yaml and add the following line to dependencies:
titanflutter: ^1.0.4
Integration with Flutter code. #
Add init code to you App
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
///register page widget builders,the key is pageName
TitanFlutter.singleton.registerPageBuilders({
'sample://firstPage': (pageName, params, _) => FirstRouteWidget(),
'sample://secondPage': (pageName, params, _) => SecondRouteWidget(),
});
///query current top page and load it
TitanFlutter.handleOnStartPage();
}
@override
Widget build(BuildContext context) => MaterialApp(
title: 'titan Flutter example',
builder: TitanFlutter.init(), ///init container manager
home: Container());
}
Integration with iOS code. #
Note: You need to add libc++ into "Linked Frameworks and Libraries"
Use FLBFlutterAppDelegate as the superclass of your AppDelegate
@interface AppDelegate : FLBFlutterAppDelegate <UIApplicationDelegate>
@end
Implement FLBPlatform protocol methods for your App.
@interface DemoRouter : NSObject<FLBPlatform>
@property (nonatomic,strong) UINavigationController *navigationController;
+ (DemoRouter *)sharedRouter;
@end
@implementation DemoRouter
- (void)openPage:(NSString *)name
params:(NSDictionary *)params
animated:(BOOL)animated
completion:(void (^)(BOOL))completion
{
if([params[@"present"] boolValue]){
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController presentViewController:vc animated:animated completion:^{}];
}else{
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController pushViewController:vc animated:animated];
}
}
- (void)closePage:(NSString *)uid animated:(BOOL)animated params:(NSDictionary *)params completion:(void (^)(BOOL))completion
{
FLBFlutterViewContainer *vc = (id)self.navigationController.presentedViewController;
if([vc isKindOfClass:FLBFlutterViewContainer.class] && [vc.uniqueIDString isEqual: uid]){
[vc dismissViewControllerAnimated:animated completion:^{}];
}else{
[self.navigationController popViewControllerAnimated:animated];
}
}
@end
Initialize TitanFlutter with FLBPlatform at the beginning of your App.
[FlutterBoostPlugin.sharedInstance startFlutterWithPlatform:router
onStart:^(FlutterViewController *fvc) {
}];
Integration with Android code. #
Init TitanFlutter in Application.onCreate()
public class MyApplication extends FlutterApplication {
@Override
public void onCreate() {
super.onCreate();
FlutterBoostPlugin.init(new IPlatform() {
@Override
public Application getApplication() {
return MyApplication.this;
}
/**
* get the main activity, this activity should always at the bottom of task stack.
*/
@Override
public Activity getMainActivity() {
return MainActivity.sRef.get();
}
@Override
public boolean isDebug() {
return false;
}
/**
* start a new activity from flutter page, you may need a activity router.
*/
@Override
public boolean startActivity(Context context, String url, int requestCode) {
return PageRouter.openPageByUrl(context,url,requestCode);
}
@Override
public Map getSettings() {
return null;
}
});
}
Basic Usage #
Concepts #
All page routing requests are being sent to the native router. Native router communicates with Native Container Manager, Native Container Manager takes care of building and destroying of Native Containers.
Use Flutter Boost Native Container to show a Flutter page in native code. #
iOS
FLBFlutterViewContainer *vc = FLBFlutterViewContainer.new;
[vc setName:name params:params];
[self.navigationController presentViewController:vc animated:animated completion:^{}];
Android
public class FlutterPageActivity extends BoostFlutterActivity {
@Override
public void onRegisterPlugins(PluginRegistry registry) {
//register flutter plugins
GeneratedPluginRegistrant.registerWith(registry);
}
@Override
public String getContainerName() {
//specify the page name register in TitanFlutter
return "sample://firstPage";
}
@Override
public Map getContainerParams() {
//params of the page
Map<String,String> params = new HashMap<>();
params.put("key","value");
return params;
}
}
or
public class FlutterFragment extends BoostFlutterFragment {
@Override
public void onRegisterPlugins(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
@Override
public String getContainerName() {
return "sample://firstPage";
}
@Override
public Map getContainerParams() {
Map<String,String> params = new HashMap<>();
params.put("key","value");
return params;
}
}
Use Flutter Boost to open a page in dart code. #
Dart
TitanFlutter.singleton.openPage("pagename", {}, true);
Use Flutter Boost to close a page in dart code. #
TitanFlutter.singleton.closePageForContext(context);
Running the Demo #
Please see the example for details.
License #
This project is licensed under the MIT License - see the LICENSE.md file for details
Acknowledgments #
- Flutter