Flutter 界面路由淺析

關鍵詞Navigator、Route、Overlay

默認狀況下,一次路由,由Navigator(route管理類)發起,Overlay(Navigator的子節點,用來掛載route的界面)切換Route(別名、界面管理類)所攜帶的界面。bash

詳情

Navigator一個StatefulWidget嵌套在MaterialApp內部,其狀態類NavigatorState(class NavigatorState extends State with TickerProviderStateMixin)能夠在路由界面內,經過Navigator.of(context)獲取。

一個標準的路由實現ide

Navigator.push(context, new MaterialPageRoute(builder: (_) {
            return MyHomePage();
          }));
          
複製代碼

push 內部動畫

Future<T> push<T extends Object>(Route<T> route) {
    route.install(_currentOverlayEntry);
    // 路由表
    _history.add(route);
    // 路由動做開始,(設置焦點,開始動畫)
    route.didPush();
    return route.popped;
  }
複製代碼

route.install(_currentOverlayEntry)做用

1.先初始化動畫相關
2. 會初始化兩個界面,一個是 _modalBarrier黑色蒙層,和咱們須要路由的界面 由 _buildModalScope方法返回ui

Iterable<OverlayEntry> createOverlayEntries() sync* {
    yield _modalBarrier = OverlayEntry(builder: _buildModalBarrier);
    yield OverlayEntry(builder: _buildModalScope, maintainState: maintainState);
  }
複製代碼

_buildModalScope 返回的界面this

_ModalScopeStatus(
    ...
        child: AnimatedBuilder(
        builder: (BuildContext context, Widget child) {
        // 界面切換動畫
          return widget.route.buildTransitions(
            context,
            widget.route.animation,
            widget.route.secondaryAnimation,
           );
        },
        child: _page ??= RepaintBoundary(
          child: Builder(
            builder: (BuildContext context) {
            // 咱們須要路由的界面
              return widget.route.buildPage(
                context,
                widget.route.animation,
                widget.route.secondaryAnimation,
              );
            },
          ),
        ),
    )
複製代碼

3.調用navigator.overlay.insertAll()插入第二部初始化的界面spa

void insertAll(Iterable<OverlayEntry> entries, { OverlayEntry above }) {
    if (entries.isEmpty)
      return;
    for (OverlayEntry entry in entries) {
      assert(entry._overlay == null);
      entry._overlay = this;
    }
    // 更新界面
    setState(() {
      final int index = above == null ? _entries.length : _entries.indexOf(above) + 1;
      _entries.insertAll(index, entries);
    });
  }
複製代碼

Overlay 嵌套Stack,經過棧來管理界面code

Widget build(BuildContext context) {
...
    return _Theatre(
      onstage: Stack(
        fit: StackFit.expand,
        children: onstageChildren.reversed.toList(growable: false),
      ),
      offstage: offstageChildren,
    );
  }
複製代碼
相關文章
相關標籤/搜索