• Flutter 局部刷新


    flutter的局部刷新的几种方式

    第一种 :使用 GlobalKey

    父组件中声明

    GlobalKey<_局部刷新对象类型State> textKey = GlobalKey();

    textKey.currentState.局部刷新的方法();

    第二种

    使用:StatefulBuilder

    第三种

    使用 StreamBuilder + StreamController  FutureBuilder & StreamBuilder

    第三种:provider  (也是异步通信

    ChangeNotifier  + ChangeNotifierProvider 

    第四种   (也是异步通信) :Flutter ValueNotifier 异步通信、ValueListenableBuilder - 知乎

    ValueNotifier + ValueListenableBuilder
     

    第一种:使用 GlobalKey

    globalkey唯一定义了某个element,它使你能够访问与element相关联的其他对象,例如buildContext、state等。
    使用场景:可以通过key.currentState拿到它的状态对象,然后就可以调用其中的onPressed方法。

    1. //请求刷新
    2. setState((){
    3. });
    4. #Stateextends StatefulWidget>
    5. @override
    6. Widget build(BuildContext context) {
    7. //构建新的Widget
    8. return new Text(_text);
    9. }

    那么,如果 我们能将 build方法中的 return new Text(_text) 暴漏出去,我们就可以实现通用的 局部刷新 Widget。

    实现方案

    1. 接口回调,将return new Text(_text);暴露出去:

    用typedef function实现

    1. //定义函数别名
    2. typedef BuildWidget = Widget Function();

    将函数别名 BuildWidget 作为参数,传递到State.build方法即可

    完整代码

    1. import 'package:flutter/material.dart';
    2. //封装 通用局部刷新工具类
    3. //定义函数别名
    4. typedef BuildWidget = Widget Function();
    5. class PartRefreshWidget extends StatefulWidget {
    6. PartRefreshWidget(Key key, this._child): super(key: key);
    7. BuildWidget _child;
    8. @override
    9. State createState() {
    10. return PartRefreshWidgetState(_child);
    11. }
    12. }
    13. class PartRefreshWidgetState extends State<PartRefreshWidget> {
    14. BuildWidget child;
    15. PartRefreshWidgetState(this.child);
    16. @override
    17. Widget build(BuildContext context) {
    18. return child.call();
    19. }
    20. void update() {
    21. print('update');
    22. setState(() {
    23. });
    24. }
    25. }

    使用:

    1. import 'package:flutter/material.dart';
    2. import 'PartRefreshWidget.dart';
    3. class GlobalKeyDemo extends StatefulWidget {
    4. @override
    5. _GlobalKeyDemoState createState() => _GlobalKeyDemoState();
    6. }
    7. class _GlobalKeyDemoState extends State<GlobalKeyDemo> {
    8. int _count = 0;
    9. //使用1 创建GlobalKey
    10. GlobalKey globalKey = new GlobalKey();
    11. @override
    12. Widget build(BuildContext context) {
    13. print('----------------build');
    14. return Scaffold(
    15. appBar: AppBar(
    16. title: Text("inheritedWidget"),
    17. ),
    18. body: Center(
    19. child: Column(
    20. mainAxisAlignment: MainAxisAlignment.center,
    21. children: [
    22. //使用2 创建通用局部刷新widget
    23. PartRefreshWidget(globalKey, () {
    24. ///创建需要局部刷新的widget
    25. return Text(
    26. '变化的:$_count',
    27. style: TextStyle(color: Colors.green),
    28. );
    29. }),
    30. Text('不变的: $_count'),
    31. RaisedButton(
    32. onPressed: () {
    33. //点击
    34. _count++;
    35. //使用3调用刷新方法
    36. globalKey.currentState.update();
    37. },
    38. ),
    39. ],
    40. ),
    41. )
    42. );
    43. }
    44. }

    转载:https://blog.csdn.net/jdsjlzx/article/details/123560075

    第二种:使用:StatefulBuilder

    使用情景:

    多选和单选

    单选的时候,选中一个就可以直接把结果返回,因此本身底部弹窗无需状态管理。但到多选的时候,需要知道当前选中的选项,有选项被点击的时候需要存储下来,当再次被点击的时候要清空这个选项,同时界面还需要同步更新,因此就涉及到状态管理了。

    实现方式 内部使用。

    在Flutter 中提供了一个 StatefulBuilder的类,提供了一个 builder方法构建有状态组件,并且提供了状态更新方法,因此在里面完成状态管理。

    在这个 builder方法中,setState其实就是对应状态组件的setState对应的方法,这个 state 就是用于控制 StatefulBuilder生成的组件的状态的。这种方式有点类似于 React的 useState的钩子函数用法

    使用的核心代码:

    1. class DemoStatefulBuilderPage extends StatelessWidget {
    2. @override
    3. Widget build(BuildContext context) {
    4. return Scaffold(
    5. //状态构建器
    6. body: buildStatefulBuilder(),
    7. );
    8. }
    9. }
    1. int _count = 0;
    2. StatefulBuilder buildStatefulBuilder() {
    3. return StatefulBuilder(
    4. //构建状态改变的Widget
    5. builder: (BuildContext context, void Function(void Function()) setState) {
    6. //居中
    7. return Center(
    8. //手势识别
    9. child: GestureDetector(
    10. child: Text("早起的年轻人 $_count"),
    11. //单击事件
    12. onTap: () {
    13. //刷新当前 StatefulBuilder 中的状态
    14. setState(() {
    15. _count++;
    16. });
    17. },
    18. ),
    19. );
    20. },
    21. );
    22. }

    第三种 使用 FutureBuilder & StreamBuilder

    使用场景:异步UI更新
    很多时候我们会依赖一些异步数据来动态更新UI,比如在打开一个页面时我们需要先从互联网上获取数据,在获取数据的过程中显示一个加载框,等获取到数据时我们再渲染页面;又比如我们想展示Stream(比如文件流、互联网数据接收流)的进度。当然StatefulWidget我们完全可以实现以上功能。但由于在实际开发中依赖异步数据更新UI的这种场景非常常见,并且当StatefulWidget中控件树较大时,更新一个属性导致整个树重建,消耗性能,因此Flutter专门提供了FutureBuilder和SteamBuilder两个组件来快速实现这种功能。

    FutureBuilder的使用

    1. const FutureBuilder({
    2. Key key,
    3. this.future, //获取数据的方法 获取用户异步处理获得数据的代码
    4. this.initialData, //初始的默认数据 初始化数据加载
    5. @required this.builder //数据快照 回调函数,暴露异步处理中的快照。这个是我们构建组件的主要组成。 主要来看一下它的构造函数:
    6. }) : assert(builder != null),
    7. super(key: key);
    1. class _MyHomePageState extends State<MyHomePage> {
    2. Future<String> mockNetworkData() async {
    3. return Future.delayed(Duration(seconds: 2), () => "我是从互联网上获取的数据");
    4. }
    5. @override
    6. Widget build(BuildContext context) {
    7. return Scaffold(
    8. appBar: AppBar(
    9. title: Text(widget.title),
    10. ),
    11. body: Center(
    12. child: Column(
    13. mainAxisAlignment: MainAxisAlignment.center,
    14. children: [
    15. Text(
    16. 'You have pushed the button this many times:',
    17. ),
    18. FutureBuilder(
    19. future: mockNetworkData(),
    20. builder: (BuildContext context, AsyncSnapshot snapshot){
    21. if(snapshot.connectionState == ConnectionState.done){
    22. if(snapshot.hasError){
    23. // 请求失败,显示错误
    24. return Text("Error: ${snapshot.error}");
    25. }else {
    26. // 请求成功,显示数据
    27. return Text("Contents: ${snapshot.data}");
    28. }
    29. }else {
    30. return CircularProgressIndicator();
    31. }
    32. }),
    33. ],
    34. ),
    35. ), // This trailing comma makes auto-formatting nicer for build methods.
    36. );
    37. }
    38. }

    SteamBuilder的使用

    1. class _MyHomePageState extends State<MyHomePage> {
    2. Stream<int> counter(){
    3. return Stream.periodic(Duration(seconds: 1), (i){
    4. return i;
    5. });
    6. }
    7. @override
    8. Widget build(BuildContext context) {
    9. return Scaffold(
    10. appBar: AppBar(
    11. title: Text(widget.title),
    12. ),
    13. body: Center(
    14. child: Column(
    15. mainAxisAlignment: MainAxisAlignment.center,
    16. children: [
    17. Text(
    18. 'You have pushed the button this many times:',
    19. ),
    20. StreamBuilder(
    21. stream: counter(),
    22. builder: (BuildContext context, AsyncSnapshot<int> snapshot){
    23. if(snapshot.hasError){
    24. return Text("Error: ${snapshot.error}");
    25. }
    26. switch (snapshot.connectionState){
    27. case ConnectionState.none:
    28. return Text("没有Stream");
    29. case ConnectionState.waiting:
    30. return Text("等待数据、、、");
    31. case ConnectionState.active:
    32. return Text("active: ${snapshot.data}");
    33. case ConnectionState.done:
    34. return Text("Stream已关闭");
    35. }
    36. return null;
    37. }),
    38. ],
    39. ),
    40. ), // This trailing comma makes auto-formatting nicer for build methods.
    41. );
    42. }
    43. }

    StreamBuilder与StreamController的详细使用:https://blog.csdn.net/u010194271/article/details/128024208

  • 相关阅读:
    JavaWeb-JSTL标签库
    48、分布式锁(基于redis实现分布式锁初级版本)
    SpringCloud进阶-搭建基本环境
    Flutter-自定义短信验证码
    JSONP 跨域访问(2), JSONP劫持
    Python爬虫实战第三例【三】【上】
    C/C++多进程高并发框架分享【内附可执行源码注释完整】
    【软件工程与实践】(第四版)第6章习题答案详解
    协程 VS 线程,Kotlin技术精讲
    Web3与Web3.0: Web3指的是去中心化和基于区块链的网络,Web3.0指的是链接或语义网络。
  • 原文地址:https://blog.csdn.net/qq_27909209/article/details/130523131