flutter 开发环境配置和生命周期学习

文章目录

        • 配置环境
          • 1. resolve.dependencies.gradle
          • 2. PUB_HOSTED_URL
          • 3. PUB_CACHE 如果项目和flutterSDK不在同一盘符,就需要配置该变量,目录指向项目所在的盘符
          • 4. FLUTTER_STORAGE_BASE_URL
          • 5. 终端代理命令
          • 6. 其他
        • 生命周期
          • 页面展示
          • 前台切回后台
          • 后台切回前台
          • 页面销毁
        • 源码分析生命周期
          • StatefulElement
          • State
          • BuildOwner
          • Element
          • ComponentElement
          • ProxyElement InheritedElement
        • 图片
        • build
        • Key
        • Offstage
        • Curve
        • Interval
        • WillPopScope
        • Backdrop
        • DefaultTextStyle
        • PhysicalModel 圆角
        • SliverAppBar
        • PreferredSize
        • android 事件机制
        • 路由的使用
        • 异步
        • 设置透明度
        • 设置点击事件
        • 宽度撑满
        • SizeBox
        • FractionallySizedBox
        • LimitedBox 和 ConstrainedBox
        • OverflowBox
        • UnconstrainedBox 解除父元素的限制
        • Theme.of(context).copyWith
        • 常用组件

配置环境
1. resolve.dependencies.gradle

Flutter安装目录/packages/flutter_tools/gradle/resolve.dependencies.gradle

maven {
url "https://maven.aliyun.com/repository/public/"
}
maven {
url "https://maven.aliyun.com/repository/central"
}
maven {
url "https://maven.aliyun.com/repository/google"
}

2. PUB_HOSTED_URL

https://pub.flutter-io.cn

3. PUB_CACHE 如果项目和flutterSDK不在同一盘符,就需要配置该变量,目录指向项目所在的盘符

D:\src\flutter_pub_cache

4. FLUTTER_STORAGE_BASE_URL

https://storage.flutter-io.cn

5. 终端代理命令

export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890

6. 其他
  1. xxx_android.iml 该文件可以让as 提示Open for Editing in Android Studio
  2. settings.gradle 定义了dev.flutter.flutter-gradle-plugin插件
生命周期
  • WidgetsBindingObserver(AppLifecycleState)
  • State
页面展示
  • 构造方法->initState->didChangeDependencies-build(到这一步页面展示出来了)
前台切回后台
  • AppLifecycleState.inactive->AppLifecycleState.paused
后台切回前台
  • AppLifecycleState.inactive->AppLifecycleState.resumed
页面销毁
  • AppLifecycleState.inactive->AppLifecycleState.paused->deactivate->dispose
源码分析生命周期

ComponentElement.mount()->StatefulElement._firstBuild->state.initState()->state.didChangeDependencies()->rebuild()->StatefulElement.performRebuild()->第一次不会调用state.didChangeDependencies()因为_didChangeDependencies=fasle,后面会通过调用activited->state.activate()并且调用StatefulElement.didChangeDependencies()方法_didChangeDependencies = true

update->state.didUpdateWidget->rebuild->…

RenderObjectToWidgetElement->update->…

BuildOwner通过StatefulElement间接驱动了state各个生命周期的触发

StatefulElement
class StatefulElement extends ComponentElement {
  StatefulElement(StatefulWidget widget)
      : _state = widget.createState(),
        super(widget) {
    state._element = this;
    state._widget = widget;
  }

  
  Widget build() => state.build(this);
  State<StatefulWidget> get state => _state!;
  State<StatefulWidget>? _state;

  
  void reassemble() {
    if (_debugShouldReassemble(_debugReassembleConfig, _widget)) {
      state.reassemble();
    }
    super.reassemble();
  }

  
  void _firstBuild() {
    assert(state._debugLifecycleState == _StateLifecycle.created);
    final Object? debugCheckForReturnedFuture = state.initState() as dynamic;
    state.didChangeDependencies();
    super._firstBuild();
  }

  
  void performRebuild() {
    if (_didChangeDependencies) {
      state.didChangeDependencies();
      _didChangeDependencies = false;
    }
    super.performRebuild();
  }

  
  void update(StatefulWidget newWidget) {
    super.update(newWidget);
    final Object? debugCheckForReturnedFuture = state.didUpdateWidget(oldWidget) as dynamic;
    rebuild(force: true);
  }

  
  void activate() {
    super.activate();
    markNeedsBuild();
  }

  
  void deactivate() {
    state.deactivate();
    super.deactivate();
  }

  
  void unmount() {
    super.unmount();
    state.dispose();
    state._element = null;
    _state = null;
  }

  
  InheritedWidget dependOnInheritedElement(Element ancestor, { Object? aspect }) {
    return super.dependOnInheritedElement(ancestor as InheritedElement, aspect: aspect);
  }

  bool _didChangeDependencies = false;

  
  void didChangeDependencies() {
    super.didChangeDependencies();
    _didChangeDependencies = true;
  }

}
State

class State {

  T get widget => _widget!;
  T? _widget;

  BuildContext get context {
    assert(() {
      if (_element == null) {
       
      }
      return true;
    }());
    return _element!;
  }
  StatefulElement? _element;

  bool get mounted => _element != null;

  
  
  void initState() {
    assert(_debugLifecycleState == _StateLifecycle.created);
  }
  
  
  
  void didUpdateWidget(covariant T oldWidget) { }

  
  
  
  void reassemble() { }


  
  void setState(VoidCallback fn) {
    assert(() {
      return true;
    }());
    final Object? result = fn() as dynamic;
    _element!.markNeedsBuild();
  }

  
  
  void deactivate() { }

  
  
  void activate() { }

  
  
  void dispose() {
    assert(_debugLifecycleState == _StateLifecycle.ready);
    assert(() {
      _debugLifecycleState = _StateLifecycle.defunct;
      return true;
    }());
    if (kFlutterMemoryAllocationsEnabled) {
      MemoryAllocations.instance.dispatchObjectDisposed(object: this);
    }
  }

  
  Widget build(BuildContext context);

  
  
  void didChangeDependencies() { }
}

BuildOwner
class BuildOwner {
  
  BuildOwner({ this.onBuildScheduled, FocusManager? focusManager }) :
      focusManager = focusManager ?? (FocusManager()..registerGlobalHandlers());

 
  VoidCallback? onBuildScheduled;

  final _InactiveElements _inactiveElements = _InactiveElements();

  final List<Element> _dirtyElements = <Element>[];
  bool _scheduledFlushDirtyElements = false;

  bool? _dirtyElementsNeedsResorting;

 

  FocusManager focusManager;


  void scheduleBuildFor(Element element) {
   
    if (element._inDirtyList) {
      _dirtyElementsNeedsResorting = true;
      return;
    }
    if (!_scheduledFlushDirtyElements && onBuildScheduled != null) {
      _scheduledFlushDirtyElements = true;
      onBuildScheduled!();
    }
    _dirtyElements.add(element);
    element._inDirtyList = true;
  }

  void lockState(VoidCallback callback) {
    try {
      callback();
    } finally {
     
    }
  }

  
  ('vm:notify-debugger-on-exception')
  void buildScope(Element context, [ VoidCallback? callback ]) {
    if (callback == null && _dirtyElements.isEmpty) {
      return;
    }
    if (!kReleaseMode) {
      Map<String, String>? debugTimelineArguments;
      FlutterTimeline.startSync(
        'BUILD',
        arguments: debugTimelineArguments
      );
    }
    try {
      _scheduledFlushDirtyElements = true;
      if (callback != null) {
       
        Element? debugPreviousBuildTarget;
        _dirtyElementsNeedsResorting = false;
        try {
          callback();
        } finally {
      
        }
      }
      _dirtyElements.sort(Element._sort);
      _dirtyElementsNeedsResorting = false;
      int dirtyCount = _dirtyElements.length;
      int index = 0;
      while (index < dirtyCount) {
        final Element element = _dirtyElements[index];
        final bool isTimelineTracked = !kReleaseMode && _isProfileBuildsEnabledFor(element.widget);
        if (isTimelineTracked) {
          Map<String, String>? debugTimelineArguments;
          FlutterTimeline.startSync(
            '${element.widget.runtimeType}',
            arguments: debugTimelineArguments,
          );
        }
        try {
          element.rebuild();
        } catch (e, stack) {
          
        }
        if (isTimelineTracked) {
          FlutterTimeline.finishSync();
        }
        index += 1;
        if (dirtyCount < _dirtyElements.length || _dirtyElementsNeedsResorting!) {
          _dirtyElements.sort(Element._sort);
          _dirtyElementsNeedsResorting = false;
          dirtyCount = _dirtyElements.length;
          while (index > 0 && _dirtyElements[index - 1].dirty) {   
            index -= 1;
          }
        }
      }
    } finally {
      for (final Element element in _dirtyElements) {
        element._inDirtyList = false;
      }
      _dirtyElements.clear();
      _scheduledFlushDirtyElements = false;
      _dirtyElementsNeedsResorting = null;
      if (!kReleaseMode) {
        FlutterTimeline.finishSync();
      }
     
    }
   
  }

 
  final Map<GlobalKey, Element> _globalKeyRegistry = <GlobalKey, Element>{};

  int get globalKeyCount => _globalKeyRegistry.length;

 
  void _registerGlobalKey(GlobalKey key, Element element) {
    _globalKeyRegistry[key] = element;
  }

  void _unregisterGlobalKey(GlobalKey key, Element element) {

    if (_globalKeyRegistry[key] == element) {
      _globalKeyRegistry.remove(key);
    }
  }



  ('vm:notify-debugger-on-exception')
  void finalizeTree() {
    if (!kReleaseMode) {
      FlutterTimeline.startSync('FINALIZE TREE');
    }
    try {
      lockState(_inactiveElements._unmountAll); // this unregisters the GlobalKeys
    } catch (e, stack) {
    } finally {
      if (!kReleaseMode) {
        FlutterTimeline.finishSync();
      }
    }
  }
}
Element
class Element {
 Set<InheritedElement>? _dependencies;
 void markNeedsBuild() {
    assert(_lifecycleState != _ElementLifecycle.defunct);
    if (_lifecycleState != _ElementLifecycle.active) {
      return;
    }
    if (dirty) {
      return;
    }
    _dirty = true;
    owner!.scheduleBuildFor(this);
  }


  void rebuild({bool force = false}) {
    try {
      performRebuild();
    } finally {
      assert(() {
        owner!._debugElementWasRebuilt(this);
        assert(owner!._debugCurrentBuildTarget == this);
        owner!._debugCurrentBuildTarget = debugPreviousBuildTarget;
        return true;
      }());
    }
    assert(!_dirty);
  }	

  
  
  void performRebuild() {
    _dirty = false;
  }
  
  
  void activate() {
    assert(_lifecycleState == _ElementLifecycle.inactive);
    assert(owner != null);
    final bool hadDependencies = (_dependencies != null && _dependencies!.isNotEmpty) || _hadUnsatisfiedDependencies;
    _dependencies?.clear();
    _hadUnsatisfiedDependencies = false;
    _updateInheritance();
    attachNotificationTree();
    if (_dirty) {
      owner!.scheduleBuildFor(this);
    }
    if (hadDependencies) {
      didChangeDependencies();
    }
  }
  
  InheritedWidget dependOnInheritedElement(InheritedElement ancestor, { Object? aspect }) {
    _dependencies ??= HashSet<InheritedElement>();
    _dependencies!.add(ancestor);
    ancestor.updateDependencies(this, aspect);
    return ancestor.widget as InheritedWidget;
  }

  
  T? dependOnInheritedWidgetOfExactType<T extends InheritedWidget>({Object? aspect}) {
    assert(_debugCheckStateIsActiveForAncestorLookup());
    final InheritedElement? ancestor = _inheritedElements == null ? null : _inheritedElements![T];
    if (ancestor != null) {
      return dependOnInheritedElement(ancestor, aspect: aspect) as T;
    }
    _hadUnsatisfiedDependencies = true;
    return null;
  }

  
  T? getInheritedWidgetOfExactType<T extends InheritedWidget>() {
    return getElementForInheritedWidgetOfExactType<T>()?.widget as T?;
  }
  
  
  
   
  ('vm:prefer-inline')
  Element? updateChild(Element? child, Widget? newWidget, Object? newSlot) {
    if (newWidget == null) {
      if (child != null) {
        deactivateChild(child);
      }
      return null;
    }

    final Element newChild;
    if (child != null) {
      bool hasSameSuperclass = true;
    
      assert(() {
        final int oldElementClass = Element._debugConcreteSubtype(child);
        final int newWidgetClass = Widget._debugConcreteSubtype(newWidget);
        hasSameSuperclass = oldElementClass == newWidgetClass;
        return true;
      }());
      if (hasSameSuperclass && child.widget == newWidget) {
        if (child.slot != newSlot) {
          updateSlotForChild(child, newSlot);
        }
        newChild = child;
      } else if (hasSameSuperclass && Widget.canUpdate(child.widget, newWidget)) {
        if (child.slot != newSlot) {
          updateSlotForChild(child, newSlot);
        }
        final bool isTimelineTracked = !kReleaseMode && _isProfileBuildsEnabledFor(newWidget);
        if (isTimelineTracked) {
          Map<String, String>? debugTimelineArguments;
          Timeline.startSync(
            '${newWidget.runtimeType}',
            arguments: debugTimelineArguments,
          );
        }
        child.update(newWidget);
        if (isTimelineTracked) {
          Timeline.finishSync();
        }
        assert(child.widget == newWidget);
        assert(() {
          child.owner!._debugElementWasRebuilt(child);
          return true;
        }());
        newChild = child;
      } else {
        deactivateChild(child);
        assert(child._parent == null);
        newChild = inflateWidget(newWidget, newSlot);
      }
    } else {
      newChild = inflateWidget(newWidget, newSlot);
    }

    return newChild;
  }
  
    
  void update(covariant Widget newWidget) {
    assert(
      _lifecycleState == _ElementLifecycle.active
        && newWidget != widget
        && Widget.canUpdate(widget, newWidget),
    );
    _widget = newWidget;
  }

  
  ('vm:prefer-inline')
  Element inflateWidget(Widget newWidget, Object? newSlot) {
    final bool isTimelineTracked = !kReleaseMode && _isProfileBuildsEnabledFor(newWidget);
    if (isTimelineTracked) {
      Map<String, String>? debugTimelineArguments;
      FlutterTimeline.startSync(
        '${newWidget.runtimeType}',
        arguments: debugTimelineArguments,
      );
    }

    try {
      final Key? key = newWidget.key;
      if (key is GlobalKey) {
        final Element? newChild = _retakeInactiveElement(key, newWidget);
        if (newChild != null) {      
          try {
            newChild._activateWithParent(this, newSlot);
          } catch (_) {
            try {
              deactivateChild(newChild);
            } catch (_) {
              // Clean-up failed. Only surface original exception.
            }
            rethrow;
          }
          final Element? updatedChild = updateChild(newChild, newWidget, newSlot);
          assert(newChild == updatedChild);
          return updatedChild!;
        }
      }
      final Element newChild = newWidget.createElement();
      newChild.mount(this, newSlot);
      return newChild;
    } finally {
      if (isTimelineTracked) {
        FlutterTimeline.finishSync();
      }
    }
  }

}
ComponentElement
abstract class ComponentElement extends Element {
  
  ComponentElement(super.widget);

  Element? _child;

  bool _debugDoingBuild = false;
  
  bool get debugDoingBuild => _debugDoingBuild;

  
  void mount(Element? parent, Object? newSlot) {
    super.mount(parent, newSlot);
    _firstBuild();
    assert(_child != null);
  }

  void _firstBuild() {
    // StatefulElement overrides this to also call state.didChangeDependencies.
    rebuild(); // This eventually calls performRebuild.
  }
  
  
  ('vm:notify-debugger-on-exception')
  void performRebuild() {
    Widget? built;
    try {
      built = build();
     
    } catch (e, stack) {
      _debugDoingBuild = false;
    } finally {
      super.performRebuild(); // clears the "dirty" flag
    }
    try {
      _child = updateChild(_child, built, slot);
      assert(_child != null);
    } catch (e, stack) {
      _child = updateChild(null, built, slot);
    }
  }
  
  Widget build();

  
  void visitChildren(ElementVisitor visitor) {
    if (_child != null) {
      visitor(_child!);
    }
  }

  
  void forgetChild(Element child) {
    assert(child == _child);
    _child = null;
    super.forgetChild(child);
  }
}
ProxyElement InheritedElement

class ProxyElement{
	
  
  void update(ProxyWidget newWidget) {
    final ProxyWidget oldWidget = widget as ProxyWidget;
    assert(widget != newWidget);
    super.update(newWidget);
    assert(widget == newWidget);
    updated(oldWidget);
    rebuild(force: true);
  }
  
  void updated(covariant ProxyWidget oldWidget) {
    notifyClients(oldWidget);
  }	
}


class InheritedElement{

  
  void notifyClients(InheritedWidget oldWidget) {
  
    for (final Element dependent in _dependents.keys) {
      assert(() {
        Element? ancestor = dependent._parent;
        while (ancestor != this && ancestor != null) {
          ancestor = ancestor._parent;
        }
        return ancestor == this;
      }());
      notifyDependent(oldWidget, dependent);
    }
  }
}









图片

flutter 开发环境配置和生命周期学习_第1张图片
flutter 开发环境配置和生命周期学习_第2张图片flutter 开发环境配置和生命周期学习_第3张图片
在这里插入图片描述
flutter 开发环境配置和生命周期学习_第4张图片

build

createState

state.element = this
state.widget = widget

firstBuild
initState()
didChangeDipendcies

super.firstBuild->rebuild->performRebuild->didChangeDependencies->build

update->didUpdate->rebuild->performRebuild->didChangeDependencies->build

setState调用当前组件的build,调用子组件的update方法

setState->Element.markNeedsBuild->BuildOwner.scheduleBuildFor->

Element
bool _inDirtyList
bool _dirty 在下一次Vsync信号的时候会build

BuildOwner
List _dirtyElements
bool _scheduledFlushDirtyElements
buildScope rebuild

WidgetsBinding
_handleBuildScheduled->ensureVisualUpdate->scheduleFrame->PlatformDispatcher.scheduleFrame Vsync信号注册完成
drawFrame()->buildScope

SchedulerBinding
handleBeginFrame->PlatformDispatcher.onBeginFrame
handleDrawFrame->PlatformDispatcher.onDrawFrame

Key

GlobalKey和PageStorageKey区别

Offstage
Curve

曲线

Interval

间隔

    const Curve switchInCurve = Interval(0.4, 1.0, curve: Curves.fastOutSlowIn);
WillPopScope
Backdrop
DefaultTextStyle
PhysicalModel 圆角
SliverAppBar
PreferredSize
android 事件机制
  dispatcheTouchEvent->onInterceptTouchEvent->子控件
  
  接收到任务分发(diapatchTouchEvent)
  总经理->部门主管->员工
  
  拦截任务(onInterceptTouchEvent,只有viewgroup有这个方法,如果哪一级部门拦截就不会再向下一级部门分发)
  总经理->部门主管->员工
  
  //处理任务消耗(onTouchEvent true自己处理(包括后续事件MOVE UP),,false返回给上级处理)
  总经理->部门主管->员工
  
  //反馈处理结果
  总经理<-部门主管<-员工
  
  
  
  总经理收到任务并通知到最小员工,如果中间有部门拦截并处理,就不会向下传递,否则继续向下传递
  
  
  员工看是否有能力处理,如果有就处理,没有返回给上一级主管反馈情况
路由的使用

1.定义

3.?. ??

null?.a{}??“abc” 和kotlin ?. ?:

异步

asyn标志是异步方法
await 这个方法会返回一个异步对象 future

future.then((value){

})

设置透明度

Opacity{
opacity:0.5
}

stack postion

listview = scrollview 和 listview

import “” show name

List.from

设置点击事件

GestureDetector(
onTab:(){
}
)

宽度撑满

fractionallySizeBox(
widthFactor:1,

)

SizeBox

具体值

FractionallySizedBox
  1. 百分比布局 相对于父布局的百分比,可以溢出父容器显示
LimitedBox 和 ConstrainedBox
  1. 设置最大值 最小值
OverflowBox

1.溢出父容器显示

UnconstrainedBox 解除父元素的限制

由于父元素设置了最大值和最小值,子元素就无法修改,但是子元素可以解除限制去设置,然后再
设置宽高

Theme.of(context).copyWith

listview 设置侧轴无效 侧轴会填充 外层包裹一层container设置值来控制

expanded 设置flex以后 子weiget设置值会无效 一般用于expanded填充或等比例分配外层weiget

stack 层叠weiget 不用设置宽高,始终填充外部的weiget 利用align和postion来实现复杂布局

AspectRatio 默认填充横向屏幕 等比例 不用设置宽度或者高度,会根据父组件来限制

1.在布局限制条件允许的范围内尽可能扩展
2.很多组件不需要设置宽高,会配合父组件一起使用

ClipOval 圆形 width height 来控制圆形

CircleAvatar 圆形头像

sizebox 间距

组件没有父组件的时候宽度(高度) 包含内容
有父组件的时候,填充全屏 button

开发插件和package

1.修改pubspec.yaml文件 名字描述 版本 作者 github主页
2.reademe.md
3.LICENSE

检查
flutter packages pub publish --dry-run
发布
flutter packages pub publish

依赖包冲突
多个依赖都引用第三方依赖
直接在下面引用这个第三方依赖 优先级最高

打包存在多个一样的so文件,冲突
packagingOptions {
pickFirst ‘**/libstlport_shared.so’
}

常用组件

1.safearea
2.expanded
3.wrap
4.animatedContainer
5.Opacity
6.FutureBuilder
7.FadeTransition
8.FloatingActionButton
9.PageView
10.Table
11.SliverAppBar
12.SliverList&SliverGrid
13.FadeinImage
14.SreamBuilder
15.InheritedModel
16.ClipRRect
17.Hero
18.CustomPaint
19.Tooltip
20.FittedBox
21.LayoutBuilder
22.AbsorbPointer
23Transform
24BackdropFilter
25Align
26Positioned
27AnimatedBuilder
28Dismissible(删除组件)
29SizedBox
30ValueListenableBuilder
31Draggable
32AnimateList
33Flexible
34MediaQuery
35Spacer
36InheritedWidget
37AnimatatedIcon
38AspectRatio
39LimitedBox
40Placeholder
41RichText
42ReorderableListView
43AnimatedSwitcher
44AnimatedPositioned
45AnimatedPadding
46IndexedStack
47Semantics
48ContrainedBox
49Stack
50.AnimatedOpacity
51.FractionallySizedBox
52.Listview
53.ListTitle
54.Container
55.SelectableText
56.DataTable
57.Slider, RangeSlider, 和 CupertinoSlider(android中的seekbar)
58.AlertDialog
59.AnimatedCrossFade
60.DraggableScrollableSheet
61.ColorFiltered
62.ToggleButtons
63. CupertinoActionSheet
64.TweenAnimationBuilder
65. Image
66. DefaultTabController TabBar
67.Drawer
68.SnackBar
69.ListWheelScrollView
70.ShaderMask
71.NotificationListener
72.Builder

你可能感兴趣的:(flutter,flutter,前端)