Flutter-状态管理

flutter的setState详细分析以及性能优化 总之,setState()方法是Flutter中非常重要的一个方法,它允许我们在widget中更新状态,并在下一帧中重新构建widget子树,从而实现高效的UI更新。总之,setState()方法是Flutter中非常重要的一个方法,它允许我们在widget中更新状态,并在下一帧中重新构建widget子树,从而实现高效的UI更新。总之,setState()方法是Flutter中非常重要的一个方法,它允许我们在widget中更新状态,并在下一帧中重新构建widget子树,从而实现高效的UI更新。 阅读详情
AI摘要

本文深入探讨Flutter状态管理的关键概念,包括setState、InheritedWidget、Provider等机制,以及ChangeNotifier的具体实现与应用案例,帮助开发者掌握高效状态管理的技巧。

一、状态管理

1.概念

        Flutter是一种响应式编程框架,能根据数据或状态变化自动更新用户界面。状态(State)指的是某个时间点上,应用中的所有变量和数据的当前值或配置,比如用户登录信息、表单数据、页面显示内容、网络请求的结果等。状态管理涉及如何追踪、更新和同步应用程序的状态,确保在数据变化时,用户界面能够正确更新。

2.方式

  • 父 Widget 管理子 Widget 的状态:适用于跟用户数据相关的状态管理

  • Widget 管理自己的状态:适用于组件私有的状态,比如UI样式

  • 父 Widget 和子 Widget混合管理:既涉及数据也涉及UI样式

  • 全局状态管理:需要同步跨组件状态

    • 事件通知+setState:Flutter 框架重新调用 build 方法,对比新的和旧的 widget 树,重建发生了变化的部分

    • InheritedWidget:在整个组件树中传递数据,通知依赖它的子树,当数据发生变化时重新构建

二、setState

        只能在 StatefulWidget 中使用,适用于局部状态更新

  • 源码

@protected
void setState(VoidCallback fn) {			//传入一个回调函数,更新有变化的状态变量
  assert(fn != null);				//断言检查有传入的回调函数
  assert(() {			//断言检查调用 setState 时的生命周期正确
    if (_debugLifecycleState == _StateLifecycle.defunct) {			//检查 State 对象是否已被销毁
      throw FlutterError.fromParts(<DiagnosticsNode>[
        ErrorSummary('setState() called after dispose(): $this'),
        ErrorDescription(
          'This error happens if you call setState() on a State object for a widget that '
          'no longer appears in the widget tree (e.g., whose parent widget no longer '
          'includes the widget in its build). This error can occur when code calls '
          'setState() from a timer or an animation callback.',
        ),
        ErrorHint(
          'The preferred solution is '
          'to cancel the timer or stop listening to the animation in the dispose() '
          'callback. Another solution is to check the "mounted" property of this '
          'object before calling setState() to ensure the object is still in the '
          'tree.',
        ),
        ErrorHint(
          'This error might indicate a memory leak if setState() is being called '
          'because another object is retaining a reference to this State object '
          'after it has been removed from the tree. To avoid memory leaks, '
          'consider breaking the reference to this object during dispose().',
        ),
      ]);
    }
    if (_debugLifecycleState == _StateLifecycle.created && !mounted) {			//检查 State 对象是否刚被创建尚未插入 Widget 树中
      throw FlutterError.fromParts(<DiagnosticsNode>[
        ErrorSummary('setState() called in constructor: $this'),
        ErrorHint(
          'This happens when you call setState() on a State object for a widget that '
          "hasn't been inserted into the widget tree yet. It is not necessary to call "
          'setState() in the constructor, since the state is already assumed to be dirty '
          'when it is initially created.',
        ),
      ]);
    }
    return true;
  }());
  final Object? result = fn() as dynamic;			//执行传入的回调函数
  assert(() {			//断言检查回调函数的返回值不是 Future
    if (result is Future) {
      throw FlutterError.fromParts(<DiagnosticsNode>[
        ErrorSummary('setState() callback argument returned a Future.'),
        ErrorDescription(
          'The setState() method on $this was called with a closure or method that '
          'returned a Future. Maybe it is marked as "async".',
        ),
        ErrorHint(
          'Instead of performing asynchronous work inside a call to setState(), first '
          'execute the work (without updating the widget state), and then synchronously '
          'update the state inside a call to setState().',
        ),
      ]);
    }
    return true;
  }());
  _element?.markNeedsBuild();			//标记状态有更新,需要被重建的元素
}

三、Provider

        封装了 InheritedWidget 的复杂性,支持多种状态管理模式(如 ChangeNotifier、ValueNotifier 等),满足不同复杂度的需求,适用于跨组件状态共享

1.ChangeNotifier

        Flutter中一个实现了 Listenable 接口的类,持有一些数据状态,提供了一个简单的机制来通知监听器状态的变化

  • 常用方法

    • 添加监听器:void addListener(VoidCallback listener)

    • 移除监听器:void removeListener(VoidCallback listener)

    • 通知所有监听器状态变化:void notifyListeners()

    • 不再需要实例时释放资源:void dispose()

  • 源码

class ChangeNotifier implements Listenable {
  int _count = 0;			//监听器个数
  List<VoidCallback?> _listeners = List<VoidCallback?>.filled(0, null);			//存储监听器回调函数
  int _notificationCallStackDepth = 0;			//跟踪通知调用栈的深度
  int _reentrantlyRemovedListeners = 0;			//跟踪在通知过程中被移除的监听器数量
  bool _debugDisposed = false;//跟踪ChangeNotifier是否被销毁

  bool _debugAssertNotDisposed() {			//断言检查 ChangeNotifier 没有被销毁
    assert(() {
      if (_debugDisposed) {
        throw FlutterError(
          'A $runtimeType was used after being disposed.\n'
          'Once you have called dispose() on a $runtimeType, it can no longer be used.',
        );
      }
      return true;
    }());
    return true;
  }

  @protected
  bool get hasListeners {			//检查是否有监听器
    assert(_debugAssertNotDisposed());
    return _count > 0;
  }

  @override
  void addListener(VoidCallback listener) {			//添加监听器
    assert(_debugAssertNotDisposed());
    if (_count == _listeners.length) {
      if (_count == 0) {
        _listeners = List<VoidCallback?>.filled(1, null);
      } else {
        final List<VoidCallback?> newListeners =
            List<VoidCallback?>.filled(_listeners.length * 2, null);
        for (int i = 0; i < _count; i++) {
          newListeners[i] = _listeners[i];
        }
        _listeners = newListeners;
      }
    }
    _listeners[_count++] = listener;
  }

  void _removeAt(int index) {			//从监听器列表中移除指定索引的监听器,并可能缩小列表大小
    _count -= 1;
    if (_count * 2 <= _listeners.length) {
      final List<VoidCallback?> newListeners = List<VoidCallback?>.filled(_count, null);

      for (int i = 0; i < index; i++)
        newListeners[i] = _listeners[i];

      for (int i = index; i < _count; i++)
        newListeners[i] = _listeners[i + 1];

      _listeners = newListeners;
    } else {
      for (int i = index; i < _count; i++)
        _listeners[i] = _listeners[i + 1];
      _listeners[_count] = null;
    }
  }

  @override
  void removeListener(VoidCallback listener) {			//移除监听器
    assert(_debugAssertNotDisposed());
    for (int i = 0; i < _count; i++) {
      final VoidCallback? _listener = _listeners[i];
      if (_listener == listener) {
        if (_notificationCallStackDepth > 0) {
          _listeners[i] = null;
          _reentrantlyRemovedListeners++;
        } else {
          _removeAt(i);
        }
        break;
      }
    }
  }

  @mustCallSuper
  void dispose() {			//ChangeNotifier不再使用时释放资源
    assert(_debugAssertNotDisposed());
    assert(() {
      _debugDisposed = true;
      return true;
    }());
  }

  @protected
  @visibleForTesting
  @pragma('vm:notify-debugger-on-exception')
  void notifyListeners() {			//通知所有监听器状态变化
    assert(_debugAssertNotDisposed());
    if (_count == 0)
      return;

    _notificationCallStackDepth++;

    final int end = _count;
    for (int i = 0; i < end; i++) {
      try {
        _listeners[i]?.call();
      } catch (exception, stack) {
        FlutterError.reportError(FlutterErrorDetails(
          exception: exception,
          stack: stack,
          library: 'foundation library',
          context: ErrorDescription('while dispatching notifications for $runtimeType'),
          informationCollector: () => <DiagnosticsNode>[
            DiagnosticsProperty<ChangeNotifier>(
              'The $runtimeType sending notification was',
              this,
              style: DiagnosticsTreeStyle.errorProperty,
            ),
          ],
        ));
      }
    }

    _notificationCallStackDepth--;

    if (_notificationCallStackDepth == 0 && _reentrantlyRemovedListeners > 0) {
      final int newLength = _count - _reentrantlyRemovedListeners;
      if (newLength * 2 <= _listeners.length) {
        final List<VoidCallback?> newListeners = List<VoidCallback?>.filled(newLength, null);

        int newIndex = 0;
        for (int i = 0; i < _count; i++) {
          final VoidCallback? listener = _listeners[i];
          if (listener != null) {
            newListeners[newIndex++] = listener;
          }
        }

        _listeners = newListeners;
      } else {
        for (int i = 0; i < newLength; i += 1) {
          if (_listeners[i] == null) {
            int swapIndex = i + 1;
            while(_listeners[swapIndex] == null) {
              swapIndex += 1;
            }
            _listeners[i] = _listeners[swapIndex];
            _listeners[swapIndex] = null;
          }
        }
      }

      _reentrantlyRemovedListeners = 0;
      _count = newLength;
    }
  }
}

2.ChangeNotifierProvider

        provider 包中提供的一种状态管理解决方案,在组件树的某个节点上创建并提供一个 ChangeNotifier 实例,管理其生命周期和监听器

  • 常用方法

    • 构造:ChangeNotifierProvider()

      • required Create<T> create:必需参数,用于创建ChangeNotifier实例,Create<T> 是一个函数类型,一般接受一个 BuildContext 并返回一个 ChangeNotifier 对象

      • Widget? child:可选参数,一般包含需要访问/监听ChangeNotifier中的数据的widget

    • ChangeNotifierProvider.value()

      • required T value:必需参数,对应的ChangeNotifier实例

      • Widget? child:可选参数,同上

  • 源码

class ChangeNotifierProvider<T extends ChangeNotifier?> extends ListenableProvider<T> {
  ChangeNotifierProvider({			//默认构造函数,创建一个新的ChangeNotifier
    Key? key,
    required Create<T> create,			//必需参数,用于创建ChangeNotifier实例,Create<T> 是一个函数类型,接受一个 BuildContext 并返回一个类型为 T 的对象
    bool? lazy,			//延迟创建,true则ChangeNotifier实例在第一次被访问时创建,false则在ChangeNotifierProvider创建时创建,默认为true
    TransitionBuilder? builder,			//用于在状态管理的基础上添加额外的 UI 逻辑
    Widget? child,			//子组件,一般包含需要访问/监听ChangeNotifier中的数据的widget
  }) : super(
          key: key,
          create: create,
          dispose: _dispose,
          lazy: lazy,
          builder: builder,
          child: child,
        );

  ChangeNotifierProvider.value({			//包装已有的ChangeNotifier
    Key? key,
    required T value,			//必需参数,包含的ChangeNotifier实例
    TransitionBuilder? builder,
    Widget? child,
  }) : super.value(
          key: key,
          builder: builder,
          value: value,
          child: child,
        );

  static void _dispose(BuildContext context, ChangeNotifier? notifier) {			//用于释放 ChangeNotifier 资源,在 Provider 被移除时自动被调用
    notifier?.dispose();
  }
}

3.Consumer

        一个特殊的Widget,在 ChangeNotifierProvider 的子组件内部使用,可以监听 ChangeNotifier 对象的变化,提供了一个builder回调函数,用于重建其子Widget

  • 源码

class Consumer<T> extends SingleChildStatelessWidget {

  Consumer({			//默认构造函数
    Key? key,
    required this.builder,			//必需参数,构建子Widget
    Widget? child,			//传递一个不依赖于 ChangeNotifier 状态的子Widget,会被传递给builder回调函数
  }) : super(key: key, child: child);

  final Widget Function(
    BuildContext context,
    T value,
    Widget? child,			//传递一个不依赖于 ChangeNotifier 状态的子Widget,提高性能
  ) builder;

  @override
  Widget buildWithChild(BuildContext context, Widget? child) {			//可以重写该函数对builder操作执行一些额外的处理
    return builder(
      context,
      Provider.of<T>(context),
      child,
    );
  }
}

4.使用示例

        1)新建一个flutter项目,将provider包添加到 pubspec.yaml 文件的依赖管理中

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.0 

        2)创建一个需要进行数据更新的类继承 ChangeNotifier

import 'package:flutter/material.dart';

class CounterViewModel extends ChangeNotifier {
  int _counter = 0;
  int get counter => _counter;

  void increment() {
    _counter++;
    notifyListeners();
  }
}

        3)在页面中创建 ChangeNotifier 实例,并使用 ChangeNotifierProvider 包裹需要监听数据的 Widget

  • ChangeNotifier 实例需要多次多处调用时,使用 ChangeNotifierProvider.value() 只包含需要更新的 Widget 结构更清晰

  • ChangeNotifier 实例不需要多次使用时,可构造 ChangeNotifierProvider 创建ChangeNotifier 实例

        4)使用 Consumer 包裹需要监听数据并更新 UI 的Widget

import 'package:flutter/material.dart';
import 'package:flutter_demo/demoViewModel.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final CounterViewModel _viewModel = CounterViewModel();

  MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<CounterViewModel>.value(
      value: _viewModel,
      child: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text(
                'You have pushed the button this many times:',
              ),
              Consumer<CounterViewModel>(			//需要根据数据状态更新UI的组件
                builder: (context, viewModel, child) {
                  return Text(
                    '${_viewModel.counter}',
                  );
                }
              )
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () => _viewModel.increment(),
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        )));
  }
}

flutter中state详解 (一)调整好心态心态是一个人能否成功的关键,如果不调整好自己的心态,是很难静下心来学习的,尤其是现在这么浮躁的社会,大部分的程序员的现状就是三点一线,感觉很累,一些大龄的程序员更多的会感到焦虑,而且随着年龄的增长,这种焦虑感会越来越强烈,那么唯一的解决办法就是调整好自己的心态,要做到自信、年轻、勤奋。这样的调整,一方面对自己学习有帮助,另一方面让自己应对面试更从容,更顺利。(二)时间挤一挤,制定好计划一旦下定决心要提升自己,那么再忙的情况下也要每天挤一挤时间,切记不可“两天打渔三天晒网”。 阅读详情

相关推荐

Flutter状态管理

什么是状态管理? 状态管理就是当某个状态发生改变的时候,告知使用该状态管理组件随之发生改变,从而达到联动效果。 为什么要使用状态管理? 方便数据的传递,减少不必要的成叠传递。 graph TB A —> C A --> D B --> C B --> D ...

勤奋的年轻人 1526

Flutter中多种状态管理方案

Flutter中有多种状态管理方案,用于管理应用程序中的状态和数据,以确保应用的可维护性和可扩展性。以下是一些常见的Flutter状态管理方法:

m0_59162559的博客 1581

Flutter - GetX状态管理

学习了Flutter&Dart也有一段时间了,从开始以为的嵌套地狱,到现在觉得也还不错!似乎没有那么可怕,在我逐渐的熟悉了Flutter以后,学会了开始封装Widget,学会了开始抽象Function,学会了添加Service,慢慢的觉得并不是这么难学,而且还开始喜欢上了Flutter来构建app,因为他方便啊,一套代码Android、IOS、Web端全部搞定,没有不兼容,一切都很丝滑。。。 最近看了Flutter的状态管理框架,flutter_bloc、MobX、GetX,这3个...

zxz414644665的专栏 8788

Flutter 状态管理

目录 一、状态管理简介 1.1 为什么需要状态管理 1.1.1 Flutter与adr/ios UI框架区别 1.1.2 状态管理框架使用场景 1.2 需要解决的问题 二、状态管理框架现有方案调研 2.1 状态管理框架 2.1.1 官方方案 2.2 市场方案调研 2.2.1 flutter_bloc 2.2.2 flutter_redux 2.2.3 fish_redux 一、状态管理简介 1.1 为什么需要状态管理 1.1.1 Flutter与adr/ios UI框架区别

zxx910509的博客 3903

flutter中的状态管理Provider

今天简单说一下flutter中的状态管理,我们这次使用provider; ps:先说一个概念,Model,模型,这里面定义了我们准备全局使用的数据,或者方法; 举个栗子:我们有一个User类,用来储存用户的信息,比如登录之后,我们会拿到用户的一些个人数据,那么这些数据就可以作为属性写在Model里,同时我们在User内部,还会提供一个upUser方法,用来更新用户信息,那么这个方法也可以写在Model中,OK,以上就是我们准备的User Model; 下面是正题,go,go,go 作为一个ios开发者,遇

iOSjack的博客 2696

Flutter GetX 之 状态管理

打开插件网站,搜索 get 插件 进行引用http://Flutter 插件网然后执行pub get进行引用。

WangQingLei0307的博客 2182

【Flutter#状态管理】Flutter 状态管理全面解析

在 Flutter 中,状态指的是影响 UI 展示的数据。例如,用户的输入、应用的配置、从服务器获取的数据等。Flutter 的 UI 是响应式的,意味着 UI 会随着状态的变化而自动更新。Riverpod 是 Flutter 中用于状态管理的一个强大的工具库,由 Provider 的作者开发,旨在解决 Provider 的一些核心问题。

qq_17387479的博客 1729

flutter-getx-concept:一个扑扑的项目,可以利用GetX的所有概念

Flutter GetX概念 :rocket:使用状态管理器GetX的Flutter项目应用程序。 概述 创建该项目的目的是应用由状态管理器实现的大多数概念。该项目使用一小部分屏幕来模拟购物车,从而实现了文件夹架构,该文件夹架构对于将屏幕上的所有小部件树放置在其中以安全地访问其父控制器是很有意义的。 总的来说,该项目是一项研究的一部分,目的是了解对我有用的,在flutter项目中实现的最佳架构模式,我也希望对您也有用。 资源 我使用了一些方法来使该项目简单,客观地满足您的建议,其中一种方法是将内部数据用作json文件,并使用assets文件夹中的图像来模拟获取api,因此您可以分叉该项目并不用担心外部资源。 带有产品列表的页面; 在类别之间切换; 列出选定类别的产品; 像在产品中一样(i tried to make this project uncomplicated, so the state of

Flutter 状态管理之GetX库

Flutter使用的是声明式UI,是通过状态去更新UI组件的,因此我们首先就要学习状态的使用。同样为了简化原本的状态使用,我们会使用Getx库。

晨曦 7191

蓝牙HCI Dongle实战:从芯片选型到协议栈集成的完整指南

本文详细介绍了蓝牙HCI Dongle的实战应用,从芯片选型到协议栈集成的完整指南。通过对比CSR8510、nRF52840等主流芯片的性能和价格,提供选型建议和避坑技巧。同时,深入解析Zephyr协议栈移植和常见问题排查,帮助开发者高效完成蓝牙项目开发。

weixin_30786657的博客 322

【cocos2dx面试题干货】--2021年最新cocos2dx面试干货(引擎篇)

【cocos2dx面试题干货】--2020年度最新cocos2dx面试干货(引擎篇 ) 大家好,我是Lampard~~ 经过春招一番艰苦奋战之后,我终于是进入了心仪的公司。 今天给大家分享一下我在之前精心准备的一套面试知识。 由于我面试的岗位是cocos2dx的开发岗,今天就先给大家分享一下引擎方面的知识。 本人亲测80%的引擎相关题目都...

Lampard的博客 1万+

【Flutter从入门到实战】⑭、状态管理、Flutter为什么需要状态管理、共享状态管理inheriedWidget的使用、Flutter官方推荐第三方Provider的使用

【Flutter从入门到实战】⑭、状态管理、Flutter为什么需要状态管理、共享状态管理inheriedWidget的使用、Flutter官方推荐第三方Provider的使用

慢慢来就很快。 3752

光电振荡器(OEO):从原理到应用,解锁高频微波信号新纪元

本文深入解析了光电振荡器(OEO)的核心原理与前沿应用。OEO通过巧妙的光-电-光转换机制,利用光学谐振腔产生高频、高纯度、低相位噪声的微波信号,有效突破了传统电子电路的频率瓶颈。文章详细拆解了其工作流程,并探讨了在雷达系统、高速光通信及精密测量等领域的硬核应用价值。

weixin_29231027的博客 366

Flutter中状态管理

在flutter开发中,我们对State来进行管理,通过State的改变,来更新界面的刷新,状态管理分为两大类: 1.短时状态管理(定时器,动画效果等) 2.应用状态管理(用户信息,购物车等) ● 共享状态管理flutter官方提供了两种方案: 1. InheritedWidget 2. Provider(Provider是目前官方推荐的全局状态管理工具) 一、InheritedWidget ...

u010707262的博客 644

USVInland 数据集实战:4个月采集27段数据,26公里内河SLAM评测

本文详细解析了USVInland数据集在内河SLAM算法评测中的应用实践。通过4个月采集的27段共26公里真实多传感器数据,该数据集有效解决了GPS信号遮挡、动态反射干扰等内河无人船SLAM核心挑战。文章从数据预处理、算法优化到性能评测,全面展示了如何利用毫米波雷达与视觉数据的时空对齐特性提升定位精度,为水上无人驾驶技术提供重要基准。

weixin_33158887的博客 342

01-SA8155 QNX 虚拟机Hypervisor

Hypervisor运行在Host OS操作系统上,其他操作系统均在Hypervisor上运行。:Hypervisor直接运行在硬件上,操作系统在Hypervisor之上运行。终止(关闭):echo control 0 dev/vmm。路径:qnx_ap/AMSS/platform/vm/resources/关闭/终止 qvm(GVM):slay -s SIGQUIT qvm。", //host PVM --- 主机。不直接操作/dev/vmm 实现关闭,启动vm。

静虚待令,有物混成 1万+

Flutter如何状态管理

目录介绍 01.什么是状态管理 02.状态管理方案分类 03.状态管理使用场景 04.Widget管理自己的状态 05.Widget管理子Widget状态 06.简单混合管理状态 07.全局状态如何管理 08.Provider使用方法 09.订阅监听修改状态 推荐 fluter Utils 工具类库:https://github.com/yangchong211/YCFlutterUtils flutter 混合项目代码案例:https://github.com/yangchong211/YCHybr

杨充 1312

模拟IC版图DRC实战:手把手教你搞定MIM电容天线错误和ESD.10g违例

本文深入解析模拟IC版图中的MIM电容天线错误和ESD.10g违例问题,提供从错误解码到实战修复的完整指南。通过电路图修改、版图优化和验证闭环等步骤,帮助工程师高效解决DRC错误,特别适用于ADC等精密模拟电路设计。文章还分享了高级排错技巧和预防性设计策略,大幅提升流片成功率。

weixin_27697385的博客 295

Flutter【01】状态管理

Flutter 应用是 声明式 的,这也就意味着 Flutter 构建的用户界面就是应用的当前状态。当你的 Flutter 应用的状态发生改变时(例如,用户在设置界面中点击了一个开关选项)你改变了状态,这将会触发用户界面的重绘。去改变用户界面本身是没有必要的(例如 widget.setText )—你改变了状态,那么用户界面将重新构建。将开发者的重点,从UI展示转移到state的维护上。

JackWu blog 1398

开关电源中的高频振荡噪声及其抑制方法

在开关电源的工作过程中,随着开关管的开关动作,电流和电压波形会出现剧烈的波动,尤其是在开关管切换的瞬间,往往会导致较强的过冲现象。开关电源中的高频振荡噪声是导致电磁兼容问题的主要源头之一,尤其是MOS管的通断和整流二极管的反向恢复过程中,会产生较强的高频振荡噪声。通过合理调节R和C的值,可以大大缓解高频振荡带来的EMC问题,从而有效提升电源的电磁兼容性。整流二极管反向恢复时的振荡会导致高频噪声产生,这些高频噪声源可被传导到电源的输出端,甚至可能通过电源的共地路径扩散到其他电路,影响系统的稳定性和可靠性。

硬核科技 1531

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Flutter状态管理 — 探索Flutter中的状态

我遇到过很多没有了解过响应式编程框架的,或者从事后端开发,自己想用Flutter写个app玩玩的朋友,一上来,不管在哪里都用`setState`,我问为啥不用状态管理,大部分都回了一句:啥是状态管理?

txaz6的博客 1197

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Flutter中GetX状态管理的终极指南

GetX 不仅是一个状态管理库,而且是一个与路由管理和依赖注入相结合的微框架。它旨在为Flutter提供顶级的开发体验,是一个额外的轻量级但强大的解决方案。GetX有三个基本原则,它是在此基础上建立的。性能:注重内存和资源的最小消耗生产力:直观和高效的工具,结合简单和直接的语法,最终节省开发时间组织性:将业务逻辑与视图和表现逻辑解耦,没有比这更好的了。你不需要上下文在路由之间导航,也不需要有状态的小工具读完整篇文章后,你是否想知道为什么这个库的创建者给它取名为GetX?

Dream It Possible 1万+

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

上一篇: WebView与JavaScriptBridge的基本使用方式
下一篇: Flutter-Widget组件
MIILN
博客等级 码龄7年 113粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值