1、 官方簡介
Flutter是谷歌的移動UI框架,可以快速在iOS和Android上構建高質量的原生使用者介面。
官方介紹:
快速開發: 毫秒級的熱過載,修改後,您的應用介面會立即更新。使用豐富的、完全可定製的widget在幾分鐘內構建原生介面。
富有表現力和靈活的UI: 快速釋出聚焦於原生體驗的功能。分層的架構允許您完全自定義,從而實現難以置信的快速渲染和富有表現力、靈活的設計
原生效能: Flutter包含了許多核心的widget,如滾動、導航、圖示和字型等,這些都可以在iOS和Android上達到原生應用一樣的效能。
2、安裝環境
①下載FlutterSDK:
②配置vscode編輯器:
flutterchina.club/get-started…
附:vs下載地址
③vscode 命令執行flutter doctor,會提示你設定flutterSDK路徑 (如果遇到許可權問題需要用Sudo chown命令,如果遇到資料夾不存在需要手動建立對應的資料夾)
④構建第一個Flutter程式:
建立程式 :VSCode -> View -> Command palette : Flutter NewProject執行程式 :Debug -> Start Debuging
注意事項 :如果遇到 Multiple commands produce 錯誤,cocoapods匯入問題,嘗試修改build system:在Xcode選單欄 -> File -> Workspace Setting,將build system修改為legacy build system,然後clean後編譯。
⑤Hello World!:
void main() => runApp(Center(child:Text("hello,world!",textDirection: TextDirection.ltr)));
Pubspec Format介紹:
3、Widget介紹
官方佈局介紹:flutterchina.club/tutorials/l…
連結:
flutterchina.club/widgets-int…
基礎Widget:
MaterialApp:該widget在應用程式的根部建立了一些有用的widget,其中包括一個Navigator, 它管理由字串標識的Widget棧(即頁面路由棧)。Navigator可以讓您的應用程式在頁面之間的平滑的過渡。
Scaffold:實現MaterialDesign佈局Widget, 此類提供tabbar,navigationBar和bottomSheets等。
Row、 Column: 這些具有彈性空間的佈局類Widget可讓您在水平(Row)和垂直(Column)方向上建立靈活的佈局。其設計是基於web開發中的Flexbox佈局模型。
Stack: 取代線性佈局 (譯者語:和Android中的LinearLayout相似),Stack允許子 widget 堆疊, 你可以使用 Positioned 來定位他們相對於Stack的上下左右四條邊的位置。Stacks是基於Web開發中的絕度定位(absolute positioning )佈局模型設計的。
Container: Container 可讓您建立矩形視覺元素。container 可以裝飾為一個BoxDecoration, 如 background、一個邊框、或者一個陰影。 Container 也可以具有邊距(margins)、填充(padding)和應用於其大小的約束(constraints)。另外, Container可以使用矩陣在三維空間中對其進行變換。
當然還有常用的其他一些Widget就不一一羅列了,exam:Padding、Image、Clip...
但是有必要說一下:Cupertino系列Widget是基於iOS設計語言的Widget風格
4、動畫
官方詳細介紹:
個人總結:
Flutter 動畫不同於iOS動畫,一個block執行一個動畫
Flutter的動畫的核心類為:
AnimationController:控制動畫的開始,暫停,與結束,它不關心我在執行什麼動畫
Animation:這個是一個抽象類,決定動畫的資料和變化方式等,可以通過addListener去監聽其Value的變化,初始化的時候需要一個AnimationController;
開始一段動畫過程:
①AnimationController.forward();//開始動畫
②Animation.value 發生變化,並執行Animation.notifyListener()
③監聽函式執行 setState()
④子Widget 根據Animation的value值進行佈局
總結:就是不停的根據Animation的變化進行setState(),Flutter的動畫並不關心Widget的佈局方式等,只提供動畫的資料模型
5、介面跳轉
使用了 Navigator 和 Routes。一個路由是 App 中“螢幕”或“頁面”的抽象,而一個 Navigator 是管理多個路由的 widget 。你可以粗略地把一個路由對應到一個 UIViewController。Navigator 的工作原理和 iOS 中 UINavigationController 非常相似,當你想跳轉到新頁面或者從新頁面返回時,它可以 push() 和 pop() 路由。
兩種方式跳轉:
△構建路由表
void main() { runApp(MaterialApp( home: MyAppHome(), // becomes the route named '/'
routes: <String, WidgetBuilder> { '/a': (BuildContext context) => MyPage(title: 'page A'), '/b': (BuildContext context) => MyPage(title: 'page B'), '/c': (BuildContext context) => MyPage(title: 'page C'),
},
));
}//跳轉Navigator.of(context).pushNamed('/b');
△直接通過widget建立一個路由
Navigator.push(context, new MaterialPageRoute(
builder: (BuildContext context) => new FTShareHomePage(title: "ShareSDK Flutter Bridge"),
// fullscreenDialog: true,
));
△資料回傳
//比如push到位置選擇介面Map coordinates = await Navigator.of(context).pushNamed('/location');//使用者選擇了位置pop出來Navigator.of(context).pop({"lat":43.821757,"long":-79.226392});
6、Dart中的非同步
①先了解程式碼怎麼寫
Future
http.Response response = await http.get(dataURL); return json.decode(response.body);
}//呼叫loadData().then((Map data){
});
② 原理其實不重要 (手動滑稽)
官方介紹:
Dart 是單執行緒執行模型,但是它支援 Isolate(一種讓 Dart 程式碼執行在其他執行緒的方式)、事件迴圈和非同步程式設計。除非你自己建立一個 Isolate ,否則你的 Dart 程式碼永遠執行在 UI 執行緒,並由 event loop 驅動。Flutter 的 event loop 和 iOS 中的 main loop 相似——Looper 是附加在主執行緒上的。
Dart 的單執行緒模型並不意味著你寫的程式碼一定是阻塞操作,從而卡住 UI。相反,使用 Dart 語言提供的非同步工具,例如 async / await ,來實現非同步操作。
7、與原生進行互動
官方介紹連結:
flutterchina.club/platform-ch…
介紹
應用的Flutter部分通過平臺通道(platform channel)將訊息傳送到其應用程式的所在的宿主(iOS或Android)。
宿主監聽的平臺通道,並接收該訊息。然後它會呼叫特定於該平臺的API(使用原生程式語言)
程式碼示例(分享到第三方平臺):
dart程式碼怎麼寫
//建立一個channel
static const channel = const MethodChannel('com.mob.flutter/sharesdk');// invokeMethod 方法執行原生方法
static Future
}
原生層:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
FlutterMethodChannel *channel = [FlutterMethodChannel
methodChannelWithName:@"com.mob.flutter/sharesdk"
binaryMessenger:controller];
[channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
dispatch_async(dispatch_get_main_queue(), ^{
if ([call.method isEqualToString:@"share"])
{ NSMutableDictionary *params = @{}.mutableCopy; NSArray *args = call.arguments;
[params SSDKSetupShareParamsByText:args.lastObject[@"text"] images:args.lastObject[@"images"] url:args.lastObject[@"url"] title:args.lastObject[@"title"] type:SSDKContentTypeAuto];
[ShareSDK share:[args.firstObject integerValue]
parameters:params
onStateChanged:^(SSDKResponseState state, NSDictionary *userData,
SSDKContentEntity *contentEntity, NSError *error) {
NSMutableDictionary *dic = @{}.mutableCopy;
dic[@"state"] = @(state);
dic[@"userData"] = userData;
dic[@"contentEntity"] = contentEntity.dictionaryValue;
dic[@"error"] = error.userInfo; if (result)
{
result(dic);
}
}];
}
});
}];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
注意:
通道的客戶端和宿主通過通道建構函式中傳遞的通道名稱進行連線。單個應用中使用的所有通道名稱必須是不同的; 我們建議在通道名稱前加一個特殊的“域名字首”,例如 samples.flutter.io/battery(flutter 中文網google翻譯害死人)
setMethodCallHandler 回撥不在主執行緒
8、開發Package
官方介紹連結:
flutterchina.club/developing-…
步驟:
①建立一個Package工程
flutter create --template=package hello#指定org可以自動建立平臺橋接檔案和example示例path_to_fluttersdk/bin/flutter create --org com.yoozoo --template=plugin sharesdk
②實現package:lib/.dart下為外掛的flutter端程式碼,ios/Classes/HelloPlugin.m 下為 原生層實現程式碼,初始程式碼已有bridge示例
③啟動xcode,外掛bridge檔案在Pods/Development Pods/hello/Classes/下:在編輯Xcode中的iOS平臺程式碼之前,首先確保程式碼至少已經構建過一次(例如,從Xcode中執行示例應用程式或終端執行cd hello/example; flutter build ios --no-codesign)。
④自動生成api文件:
cd package工程目錄export FLUTTER_ROOT=~/dev/flutter$FLUTTER_ROOT/bin/cache/dart-sdk/bin/dartdoc
⑤釋出前檢查:
//過程會提示你完善pubspec.yaml,關於example和test的警告可無視flutter packages pub publish --dry-run
⑥釋出:
flutter packages pub publis
關於分包: 對於ShareSDK和支付這樣的Plugin需要分包且cocoapods含有subspec的,需要開發者在設定完dependences後手動去 packageName.podspec 設定對應的依賴,然後執行 Flutter upgrade package
To learn more about a Podspec see guides.cocoapods.org/syntax/pods… do |s|
s.name = 'sharesdk_flutter'
s.version = '0.0.1'
s.summary = 'flutter plugin for sharesdk.'
s.deion = 'ShareSDK is the most comprehensive Social SDK in the world,which share easily with 40+ platforms.'
s.homepage = 'www.mob.com'
s.license = { :file => '../LICENSE' }
s.author = { 'Mob' => 'mobproducts@163.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.dependency 'Flutter'
s.dependency 'mob_sharesdk'# s.dependency 'mob_sharesdk/ShareSDKUI'# s.dependency 'mob_sharesdk/ShareSDKPlatforms/QQ'# s.dependency 'mob_sharesdk/ShareSDKPlatforms/SinaWeibo'# s.dependency 'mob_sharesdk/ShareSDKPlatforms/WeChat'# s.dependency 'mob_sharesdk/ShareSDKPlatforms/Facebook'# s.dependency 'mob_sharesdk/ShareSDKPlatforms/Twitter'
s.ios.deployment_target = '8.0'end
附:
ShareSDK官方package主頁:
個人學習Demo github地址:
ShareSDK package開發git: github.com/MobClub/Sha…
個人爬坑記錄:
如何給圖片設定圓角
Clip系列的Widget可以嘗試一下,比如 ClipRRect。這種裝飾反而不好做
如何設定圖片Slice
image Widget有slice屬性,但是注意你的圖片一定要在拉伸狀態,否則會顯示異常
如何設定預設ListView 底部顯示
ListView 的reverse 設定成true 然後吧scroll的offset設定成 0 既可以,使用與 IM 訊息列表等場景
ListView 沉浸式狀態列怎麼弄的
ListView 預設會偏離狀態列,目前解決方案是scrollable + column
如何優雅的設定鍵盤彈出偏移動畫
巢狀一個safaArea widget,會預設偏移
如何解決 ListView Widget複用問題
AutomaticKeepAliveClientMixin
多繼承問題怎麼解決
mixin, 什麼是mixin :
slider預設padding怎麼解決