Flutter使用簡報android
一個Android開發快速入門Flutter (二) c++
接上一篇博客,入門Flutter(一)中的內容相對來講更加全局一些,並無涉及到具體控件的使用,本篇入門會更加深刻一些,不過仍是停留在總覽的地步,不會對每個控件進行深刻探究。app
在Android中咱們經過Activity自帶的方法或者在Application中註冊ActivityLifecycleCallbacks接口進行生命週期監聽。在Flutter中固然沒有相關的概念(由於連Activity的概念也沒有)less
不過Flutter仍是有方法去監聽app狀態的,不然就沒辦法響應切換到後臺這種狀況了。async
先來講說監聽方法,咱們能夠經過繼承WidgetsBindingObserver,該類中存在一個回調方法didChangeAppLifecycleState,用於表示當前應用狀態改變。(固然WidgetsBindingObserver 中還有其餘不少狀態回調,好比一個route 被push 或者pop,好比橫豎屏變化,好比用戶locales切換,是否存在內存壓力,輔助功能切換等。)ide
具體代碼以下學習
import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter/material.dart'; class LifecycleWatcher extends StatefulWidget { @override _LifecycleWatcherState createState() => _LifecycleWatcherState(); } //多重繼承了 WidgetsBindingObserver class _LifecycleWatcherState extends State<LifecycleWatcher> with WidgetsBindingObserver { AppLifecycleState _lastLifecycleState; //至關於初始化 @override void initState() { super.initState(); //註冊應用聲明週期監聽 WidgetsBinding.instance.addObserver(this); } //至關於銷燬 @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } //監聽應用聲明週期方法 @override void didChangeAppLifecycleState(AppLifecycleState state) { print("current state is $state"); setState(() { _lastLifecycleState = state; }); } @override Widget build(BuildContext context) { if (_lastLifecycleState == null) return Text('This widget has not observed any lifecycle changes.', textDirection: TextDirection.ltr); return Text( 'The most recent lifecycle state this widget observed was: $_lastLifecycleState.', textDirection: TextDirection.ltr); } } class MyApp extends StatelessWidget { static const platform = const MethodChannel('app.channel.shared.data'); @override Widget build(BuildContext context) { // TODO: implement build return MaterialApp( title: 'Sample App', theme: ThemeData( primarySwatch: Colors.blue, ), home: Scaffold( appBar: AppBar( title: Text("Sample App"), ), body: Center(child: LifecycleWatcher()), //添加一個懸浮按鈕,該按鈕點擊後觸發_updateText方法 floatingActionButton: FloatingActionButton( onPressed: _updateText, tooltip: 'Goto Next', child: Icon(Icons.update), ), ), ); } /** * 這裏定義一個native方法,用於打開一個新的activity,這個activity是一個dialog模式的,意味着會調用當前 * activity的 onPause,可是不會調用onStop */ void _updateText() async{ await platform.invokeMethod("gotoNext"); } } void main() { runApp(MyApp()); }
native生命週期 | flutter生命週期 | |
打開app | onCreate->onStart->onResume | 無 |
打開dialog actiivty | onPause | AppLifecycleState.inactive |
關閉 dialog actiivty | onResume | AppLifecycleState.resumed |
home | onPause->onStop | AppLifecycleState.inactive -> AppLifecycleState.paused |
返回app | onStart->onResume | AppLifecycleState.inactive -> AppLifecycleState.resumed |
返回鍵退出 | onPause->onStop->onDestory | AppLifecycleState.inactive -> AppLifecycleState.paused |
先看看Flutter有哪幾種狀態 (這個地方就很是困惑了,由於官方文檔上寫的和我實際測試的存在區別,基於不迷信書本的理念,我實事求是貼出觀測狀況,有錯誤還請你們指正下)測試
AppLifecycleState.inactive 應用處於非活動狀態,而且沒有接收到用戶輸入。在Android中,這對應應用在前臺非活動狀態,好比分屏應用,電話,畫中畫應用,系統對話框或者其餘窗口。相似於onPause,可是又不徹底是,由於在返回app的時候也會先進入inactive狀態,而後再resumed。
AppLifecycleState.paused 當應用對於用戶不可見,不響應輸入,而且在後臺運行。至關於android中的onStop 。處於這個狀態的app隨時都會進入suspending掛起狀態。
AppLifecycleState.resumed 至關於android中的onPostResume(onResume以後執行),表示應用可見而且響應輸入.
AppLifecycleState.suspending 應用處於掛起狀態。暫時尚未見到這種狀態。
在Flutter中有兩個方式來添加點擊事件:
1.若是widget自己支持事件分發,好比RaisedButton,它有一個onPressed參數,這種狀況咱們能夠直接使用
@override Widget build(BuildContext context) { return RaisedButton( onPressed: () { print("click"); }, child: Text("Button")); }
2.若是widget自己不支持事件分發,那麼就須要把這個控件包裹在一個GestureDetector控件中,而且響應onTab參數。
class SampleApp extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Center( child: GestureDetector( child: FlutterLogo( size: 200.0, ), onTap: () { print("tap"); }, ), )); } }
實際上咱們已經在前面簽名版的時候監聽過一些手勢事件了,這裏列舉一下GestureDetector可以響應的事件
點擊:
onTabDown -> 相似於ACTION_DOWN
onTabUp -> ACTION_UP
onTab -> 點擊事件
onTabCancel ->點擊被取消,觸發了onTabDown,可是不會觸發onTabUp 和 onTab
雙擊:
onDoubleTab
長按
onLongPress
垂直拖動
onVerticalDragStart 和屏幕接觸,而且可能會開始垂直的移動
onVerticalDragUpdate 和屏幕接觸,在垂直方向上進一步移動
onVerticalDragEnd 以前與屏幕接觸的指針再也不於屏幕接觸,而且在中止接觸時有一個移動速度
水平拖動
onHorizontalDragStart
onHorizontalDragUpdate
onHorizontalDragEnd
咱們能夠到Google Fonts下載各類字體
首先咱們須要先準備好咱們的字體文件ttf,而且將其放入Flutter app下面,好比放在fonts文件夾中
awesome_app/ fonts/ Raleway-Regular.ttf Raleway-Italic.ttf RobotoMono-Regular.ttf RobotoMono-Bold.ttf
和android中直接加載字體到textview中不一樣,咱們須要在pubspec.yaml文件中註冊咱們的字體.
fonts: - family: Raleway fonts: - asset: fonts/Raleway-Regular.ttf - asset: fonts/Raleway-Italic.ttf style: italic - family: RobotoMono fonts: - asset: fonts/RobotoMono-Regular.ttf - asset: fonts/RobotoMono-Bold.ttf weight: 700
family表示字體的名字,咱們在TextStyle對象(用於肯定字體樣式的對象)的fontFamily中填入family值來使用這個字體。
asset指向字體文件的地址。在打包時這些字體文件會被打包到應用程序中。
同一種字體能夠有不一樣的輪廓。
weight 用來用來表示字體的粗細,值在100到900之間,是100的整數倍。咱們能夠在TextStyle的fontWeight中設置這個值。
style 表示字體是斜體仍是正常,能夠在TextStyle的fontStyle中指定。
咱們刻經過在主題中設置fontFamily來改變默認字體,固然也能夠在單獨的控件中使用
MaterialApp( title: 'Custom Fonts', // Set Raleway as the default app font theme: ThemeData(fontFamily: 'Raleway'), home: MyHomePage(), );
或者
Text( 'Roboto Mono sample', style: TextStyle(fontFamily: 'RobotoMono'), );
若是咱們給TextStyle設置的weight或者style沒有對應的asset,那麼系統就會自動選擇這種字體裏的一種風格。
很遺憾,當前在Flutter中沒有辦法直接調用c++的代碼,全部c++代碼都須要通過native層的中轉,建立custom plugin或者直接MethodChannel。
這是一個Flutter插件,可以在NSUserDefaults(ios中的數據存儲)和Shared Preferences的功能.
這個目前Flutter對於Firebase仍是有插件的,可是其餘的三方推送就沒有插件了,只能本身開發或者創建Channel
至此,咱們已經入門了Flutter,隨着學習的深刻,發現Flutter並非一個簡單的UI替代方案,它已是一整套完整的開發流程。另外最近Flutter的火熱程度感受急速上升,或許真能在移動開發界掀起顛覆也說不定。另外,聽說Flutter也在向其餘平臺進軍,它的目標是整合全部前端開發(PC應用,網頁前端等等)。而且在2019年的I/O大會上還會有更多的分享。