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,
    );
  }
复制代码
相关文章
相关标签/搜索