|
| 1 | +--- |
| 2 | +title: 'Flutter' |
| 3 | +link: https://raw.githubusercontent.com/NativeScript/ui-kit/main/packages/flutter/README.md |
| 4 | +--- |
| 5 | + |
| 6 | +<div style="width: 100%; padding: 1.2em 0em"> |
| 7 | + <img alt="github logo" src="../assets/images/github/GitHub-Mark-32px.png" style="display: inline; margin: 1em 0.5em 1em 0em"> |
| 8 | + <a href="https://github.com/NativeScript/ui-kit/tree/main/packages/flutter" target="_blank" noopener>Flutter</a> |
| 9 | +</div> |
| 10 | + |
| 11 | +# @nativescript/flutter |
| 12 | + |
| 13 | +Use Flutter with NativeScript projects by creating a [Flutter module](https://docs.flutter.dev/add-to-app) in the root of your project. |
| 14 | + |
| 15 | +## Usage |
| 16 | + |
| 17 | +**Prerequisites:** |
| 18 | + |
| 19 | +- [NativeScript installed](https://beta.docs.nativescript.org/setup/) |
| 20 | +- [Flutter installed](https://docs.flutter.dev/get-started/install) |
| 21 | + |
| 22 | +### 1. Add Flutter to a NativeScript app |
| 23 | + |
| 24 | +You can use Flutter in any existing NativeScript app or by creating a new one with `ns create`. |
| 25 | + |
| 26 | +We can then create a Flutter module at the root of the project directory: |
| 27 | + |
| 28 | +```bash |
| 29 | +flutter create --template module flutter_views |
| 30 | +``` |
| 31 | + |
| 32 | +_Note_: You can run `flutter run --debug` or `flutter build ios` from inside this `flutter_views` folder as any normal Flutter project to develop it. |
| 33 | + |
| 34 | +Learn more from the [Flutter documentation here](https://docs.flutter.dev/add-to-app). |
| 35 | + |
| 36 | +### 2. Configure your Dart code to have named entry points |
| 37 | + |
| 38 | +Named entry points allow us to use different Flutter views in our NativeScript app by matching the entry point with the view id, for example: `<Flutter id="myFlutterView" />` |
| 39 | + |
| 40 | +- `main.dart` |
| 41 | + |
| 42 | +```ts |
| 43 | +@pragma('vm:entry-point') |
| 44 | +void myFlutterView() => runApp(const MyFlutterView()); |
| 45 | +``` |
| 46 | + |
| 47 | +### 3. Configure platforms for usage |
| 48 | + |
| 49 | +#### iOS |
| 50 | + |
| 51 | +`App_Resources/iOS/Podfile` should contain the following to reference our Flutter module. |
| 52 | + |
| 53 | +```ruby |
| 54 | +platform :ios, '14.0' |
| 55 | + |
| 56 | +flutter_application_path = '../../flutter_views' |
| 57 | +load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') |
| 58 | +install_all_flutter_pods(flutter_application_path) |
| 59 | + |
| 60 | +post_install do |installer| |
| 61 | + flutter_post_install(installer) if defined?(flutter_post_install) |
| 62 | +end |
| 63 | +``` |
| 64 | + |
| 65 | +Add Flutter debug permissions to `App_Resources/iOS/Info.plist`: |
| 66 | + |
| 67 | +```xml |
| 68 | +<key>NSLocalNetworkUsageDescription</key> |
| 69 | +<string>Allow Flutter tools to debug your views.</string> |
| 70 | +<key>NSBonjourServices</key> |
| 71 | +<array> |
| 72 | + <string>_dartobservatory._tcp</string> |
| 73 | +</array> |
| 74 | +``` |
| 75 | + |
| 76 | +#### Android |
| 77 | + |
| 78 | +`App_Resources/Android/app.gradle` should contain the following: |
| 79 | + |
| 80 | +```ts |
| 81 | +android { |
| 82 | + // ... |
| 83 | + |
| 84 | + defaultConfig { |
| 85 | + // ... |
| 86 | + |
| 87 | + // Add this section: |
| 88 | + ndk { |
| 89 | + // Filter for architectures supported by Flutter. |
| 90 | + abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64' |
| 91 | + } |
| 92 | + } |
| 93 | +``` |
| 94 | +
|
| 95 | +`App_Resources/Android/settings.gradle` (create file if needed) should contain the following: |
| 96 | +
|
| 97 | +```ts |
| 98 | +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() |
| 99 | + |
| 100 | +def plugins = new Properties() |
| 101 | +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') |
| 102 | +if (pluginsFile.exists()) { |
| 103 | + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } |
| 104 | +} |
| 105 | + |
| 106 | +plugins.each { name, path -> |
| 107 | + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() |
| 108 | + include ":$name" |
| 109 | + project(":$name").projectDir = pluginDirectory |
| 110 | +} |
| 111 | + |
| 112 | +setBinding(new Binding([gradle: this])) |
| 113 | +evaluate(new File( |
| 114 | + settingsDir.parentFile, |
| 115 | + // use the flutter module folder name you created here. |
| 116 | + // for example, a flutter module called 'flutter_views' exist at root of project |
| 117 | + '../flutter_views/.android/include_flutter.groovy' |
| 118 | +)) |
| 119 | +``` |
| 120 | +
|
| 121 | +Build the module anytime you want to see your Dart changes reflected in NativeScript: |
| 122 | +
|
| 123 | +```bash |
| 124 | +cd flutter_views/.android |
| 125 | + |
| 126 | +# This will build debug mode |
| 127 | +./gradlew Flutter:assemble |
| 128 | + |
| 129 | +# This will build release mode |
| 130 | +./gradlew Flutter:assembleRelease |
| 131 | +``` |
| 132 | +
|
| 133 | +### 4. Install @nativescript/flutter |
| 134 | +
|
| 135 | +```bash |
| 136 | +npm install @nativescript/flutter |
| 137 | +``` |
| 138 | +
|
| 139 | +### 5. Use `Flutter` wherever desired |
| 140 | +
|
| 141 | +Be sure to initialize the Flutter engine before bootstrapping your app, typically in `app.ts` or `main.ts`: |
| 142 | +
|
| 143 | +```ts |
| 144 | +import { init } from '@nativescript/flutter' |
| 145 | +init() |
| 146 | + |
| 147 | +// bootstrap app... |
| 148 | +``` |
| 149 | +
|
| 150 | +When using flavors, you can just register the element for usage in your markup: |
| 151 | +
|
| 152 | +```ts |
| 153 | +import { Flutter } from '@nativescript/flutter' |
| 154 | + |
| 155 | +// Angular |
| 156 | +import { registerElement } from '@nativescript/angular' |
| 157 | +registerElement('Flutter', () => Flutter) |
| 158 | + |
| 159 | +// Solid |
| 160 | +import { registerElement } from 'dominative' |
| 161 | +registerElement('flutter', Flutter) |
| 162 | + |
| 163 | +// Svelte |
| 164 | +import { registerNativeViewElement } from 'svelte-native/dom' |
| 165 | +registerNativeViewElement('flutter', () => Flutter) |
| 166 | + |
| 167 | +// React |
| 168 | +import { registerElement } from 'react-nativescript' |
| 169 | +registerElement('flutter', () => Flutter) |
| 170 | + |
| 171 | +// Vue |
| 172 | +import Vue from 'nativescript-vue' |
| 173 | +Vue.registerElement('Flutter', () => Flutter) |
| 174 | +``` |
| 175 | +
|
| 176 | +Use `Flutter` anywhere. |
| 177 | +
|
| 178 | +```xml |
| 179 | +<Flutter id="myFlutterView" /> |
| 180 | +``` |
| 181 | +
|
| 182 | +## Troubleshooting |
| 183 | +
|
| 184 | +Common troubleshooting tips: |
| 185 | +
|
| 186 | +### Android |
| 187 | +
|
| 188 | +Before running Android, you will want to build the flutter module first. Otherwise you may see this error: |
| 189 | +
|
| 190 | +```cli |
| 191 | +Transform's input file does not exist: flutter_views/.android/Flutter/build/intermediates/flutter/debug/libs.jar |
| 192 | +``` |
| 193 | +
|
| 194 | +You can fix by running the following: |
| 195 | +
|
| 196 | +```bash |
| 197 | +cd flutter_views/.android |
| 198 | + |
| 199 | +# This will build debug mode |
| 200 | +./gradlew Flutter:assemble |
| 201 | + |
| 202 | +# This will build release mode |
| 203 | +./gradlew Flutter:assembleRelease |
| 204 | +``` |
| 205 | +
|
| 206 | +## License |
| 207 | +
|
| 208 | +Apache License Version 2.0 |
0 commit comments