flutter學習日記(三)————Flutter的生命週期和路由

Flutter的生命週期

Flutter主要有兩種:無狀態的 StatelessWidget和有狀態的 StatefulWidgetbash

1. StatelessWidget

一個 StatelessWidget 是不能被改變的,好比:Icon、Text等。因爲不可改變,所以並無什麼生命週期。less

2. StatefulWidget

一個 StatefulWidget 是有狀態的,可變的。一個 StatefulWidget 組件能夠經過定義它的 State 來進行對組件數據狀態的存儲和修改。那麼它的State應該是有一系列的生命週期。async

image

上圖就是 State 的生命週期圖。ide

  1. StatefulWidget.createState()Framework 調用會經過調用 StatefulWidget.createState() 來建立一個 State。函數

  2. initState()新建立的 State 會和一個 BuildContext 產生關聯,此時認爲 State 已經被安裝好了,initState() 函數將會被調用。一般,咱們能夠重寫這個函數,進行初始化操做。字體

  3. didChangeDependencies()在 initState() 調用結束後,這個函數會被調用。事實上,當 State 對象的依賴關係發生變化時,這個函數總會被 Framework 調用。ui

  4. build()通過以上步驟,系統認爲一個 State 已經準備好了,就會調用 build() 來構建視圖。咱們須要在這個函數中,返回一個 Widget。idea

  5. deactivate()當 State 被暫時從視圖樹中移除時,會調用這個函數。頁面切換時,也會調用它,由於此時 State 在視圖樹中的位置發生了變化,須要先暫時移除後添加。spa

    ⚠️注意,重寫的時候必需要調用 super.deactivate()。code

  6. dispose()當 State 被永久的從視圖樹中移除,Framework 會調用該函數。在銷燬前觸發,咱們能夠在這裏進行最終的資源釋放。在調用這個函數以前,總會先調用 deactivate()。

    ⚠️注意,重寫的時候必需要調用 super.dispose()。

  7. didUpdateWidget(covariant T oldWidget)當 widget 的配置發生變化時,會調用這個函數。好比,Hot-reload 的時候就會調用這個函數。這個函數調用後,會調用 build()。

  8. setState()當我須要更新 State 的視圖時,須要手動調用這個函數,它會觸發 build() 。

Flutter的路由

Flutter裏面的路由主要是經過Navigator這個類進行控制的,當你想從這個頁面跳到另一個頁面的時候,經過Navigator便可 ⚠️調用的時候要注意頁面是入棧操做,千萬別累積了太多的頁面

這裏爲了更加直觀的展現路由之間的跳轉和轉換,我將我項目裏面封裝的一個NavigatorUtils的代碼展示出來

import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_xinqiu/page/home_page.dart';
import 'package:flutter_xinqiu/page/login_page.dart';
import 'package:flutter_xinqiu/page/noob_setting_page.dart';
import 'package:flutter_xinqiu/page/user_idea_page.dart';
import 'package:flutter_xinqiu/widget/custom_route.dart';

/**
 * 路由跳轉
 * Created by xiaocheng123
 * Date: 2019-7-8
 */
class NavigatorUtils {
  ///替換
  static pushReplacementNamed(BuildContext context, String routeName) {
    Navigator.pushReplacementNamed(context, routeName);
  }

  ///切換無參數頁面
  static pushNamed(BuildContext context, String routeName) {
    Navigator.pushNamed(context, routeName);
  }

  ///主頁
  static goHome(BuildContext context) {
    Navigator.pushReplacementNamed(context, HomePage.sName);
  }

  ///登陸頁
  static goLogin(BuildContext context) {
    // Navigator.pushReplacementNamed(context, LoginPage.sName);
    Navigator.of(context).pushAndRemoveUntil(
    new MaterialPageRoute(builder: (context) => new LoginPage()
    ), (route) => route == null);
  }

  ///新手設置頁面
  static goNoobSetting(BuildContext context) {
    Navigator.of(context).push(CustomRoute(NoobSettingPage()));
  }

  ///意見反饋設置頁面
  static goUserIdea(BuildContext context) {
    Navigator.push(context,
        new CupertinoPageRoute(builder: (context) => pageContainer(UserIdeaPage())));
  }

  ///公共打開方式
  static NavigatorRouter(BuildContext context, Widget widget) {
    return Navigator.push(context,
        new CupertinoPageRoute(builder: (context) => pageContainer(widget)));
  }

  ///Page頁面的容器,作一次通用自定義
  static Widget pageContainer(widget) {
    return MediaQuery(

        ///不受系統字體縮放影響
        data: MediaQueryData.fromWindow(WidgetsBinding.instance.window)
            .copyWith(textScaleFactor: 1),
        child: widget);
  }
}

複製代碼

在代碼裏面能夠將跳轉到某個路由進行封裝起來,這樣進行路由跳轉的時候直接引用便可

相關文章
相關標籤/搜索