【老孟Flutter】Flutter 中與平臺相關的生命週期

老孟導讀:關於生命週期的文章共有2篇,一篇(此篇)是介紹 Flutter 中Stateful 組件的生命週期。

第二篇是 Flutter 中與平臺相關的生命週期,html

博客地址:http://laomengit.com/blog/20201227/%E7%9B%B8%E5%85%B3%E5%B9%B3%E5%8F%B0%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.htmlgit

博客中還有更多精彩文章,也歡迎加入 Flutter 交流羣。微信

此篇文章所說的生命週期與 StatefulWidget 組件的生命週期是不一樣的,這裏平臺相關的生命週期指的是特定平臺相關操做所產生的生命週期,好比 Android 中 App 退到後臺後的onPause等。app

有人下場景,App正在播放視頻,此時回到手機桌面或者切換到其餘App,那麼此時視頻應該暫停播放,Flutter 中使用 AppLifecycleState 實現:less

class AppLifecycle extends StatefulWidget {
  @override
  _AppLifecycleState createState() => _AppLifecycleState();
}

class _AppLifecycleState extends State<AppLifecycle>
    with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      //TODO
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('App 生命週期'),
      ),
      body: Center(
        child: Text(''),
      ),
    );
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }
}

重點是重寫 didChangeAppLifecycleState 方法,AppLifecycleState 中的狀態包括:resumed、inactive、paused、detached。async

didChangeAppLifecycleState 方法的回調來源於系統的通知(notifications),正常狀況下,App是能正常接收到這些通知,但有的狀況下是沒法接收到通知的,好比用戶強制關機、手機沒有電自動關機等。ide

下面對其狀態詳細說明:ui

  • resumed:應用程序可見且響應用戶輸入。
  • inactive:應用程序處於非激活狀態,沒法響應用戶輸入。在iOS上,打電話、響應TouchID請求、進入應用程序切換器或控制中心都處於此狀態。在Android上,分屏應用,打電話,彈出系統對話框或其餘窗口等。
  • pause:應用程序不可見且沒法響應用戶輸入,運行在後臺。處於此狀態時,引擎將不會調用 Window.onBeginFrameWindow.onDrawFrame
  • detached:應用程序仍寄存在Flutter引擎上,但與平臺 View 分離。處於此狀態的時機:引擎首次加載到附加到一個平臺 View的過程當中,或者因爲執行 Navigator pop ,view 被銷燬。

下面是關於生命週期常常遇到的問題:this

有2個頁面A和B,在B頁面點擊返回鍵返回到A,didChangeAppLifecycleState 不回調

其實這個問題大部分人是想要實現相似於Android 中 onResume 中的功能,用 didChangeAppLifecycleState 是沒法實現此功能的,didChangeAppLifecycleState 是對應於整個應用程序的,而不是 Flutter 中 不一樣的路由(頁面)。spa

從A->B,在從B返回A,A從新加載數據使用以下方法:

A頁面代碼:

class A extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(onPressed: ()async{
      var result = await Navigator.of(context).push(MaterialPageRoute(builder: (context){
        return B();
      }));
      //從B返回到A時,執行下面的代碼
      //TODO 加載數據
    });
  }
}

B頁面代碼:

class B extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(onPressed: (){
      Navigator.of(context).pop('返回的參數');
    });
  }
}

交流

老孟Flutter博客(330個控件用法+實戰入門系列文章):http://laomengit.com

歡迎加入Flutter交流羣(微信:laomengit)、關注公衆號【老孟Flutter】:

相關文章
相關標籤/搜索