文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Flutter 局部刷新

2023-09-05 06:54

关注

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方法。

  //请求刷新  setState((){      });    #State  @override  Widget build(BuildContext context) {    //构建新的Widget    return new Text(_text);  } 

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

实现方案

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

用typedef function实现

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

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

完整代码

 import 'package:flutter/material.dart'; //封装 通用局部刷新工具类//定义函数别名typedef BuildWidget = Widget Function(); class PartRefreshWidget extends StatefulWidget {   PartRefreshWidget(Key key, this._child): super(key: key);  BuildWidget _child;   @override  State createState() {    return PartRefreshWidgetState(_child);  } } class PartRefreshWidgetState extends State {   BuildWidget child;   PartRefreshWidgetState(this.child);   @override  Widget build(BuildContext context) {    return child.call();  }   void update() {    print('update');    setState(() {     });  }  }

使用:

import 'package:flutter/material.dart'; import 'PartRefreshWidget.dart'; class GlobalKeyDemo extends StatefulWidget {  @override  _GlobalKeyDemoState createState() => _GlobalKeyDemoState();} class _GlobalKeyDemoState extends State {  int _count = 0;   //使用1 创建GlobalKey  GlobalKey globalKey = new GlobalKey();   @override  Widget build(BuildContext context) {    print('----------------build');     return Scaffold(        appBar: AppBar(          title: Text("inheritedWidget"),        ),        body: Center(          child: Column(            mainAxisAlignment: MainAxisAlignment.center,            children: [              //使用2 创建通用局部刷新widget              PartRefreshWidget(globalKey, () {                ///创建需要局部刷新的widget                return Text(                  '变化的:$_count',                  style: TextStyle(color: Colors.green),                );              }),              Text('不变的: $_count'),              RaisedButton(                onPressed: () {                  //点击                  _count++;                  //使用3调用刷新方法                  globalKey.currentState.update();                },              ),            ],          ),        )    );  }}

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

第二种:使用:StatefulBuilder

使用情景:

多选和单选

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

实现方式 内部使用。

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

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

使用的核心代码:

class DemoStatefulBuilderPage extends StatelessWidget {  @override  Widget build(BuildContext context) {    return Scaffold(      //状态构建器      body: buildStatefulBuilder(),    );  }}
  int _count = 0;  StatefulBuilder buildStatefulBuilder() {    return StatefulBuilder(      //构建状态改变的Widget      builder: (BuildContext context, void Function(void Function()) setState) {        //居中        return Center(          //手势识别          child: GestureDetector(            child: Text("早起的年轻人 $_count"),            //单击事件            onTap: () {              //刷新当前  StatefulBuilder 中的状态              setState(() {                _count++;              });            },          ),        );      },    );  }

第三种 使用 FutureBuilder & StreamBuilder

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

FutureBuilder的使用

  const FutureBuilder({    Key key,    this.future,          //获取数据的方法  获取用户异步处理获得数据的代码    this.initialData,   //初始的默认数据  初始化数据加载    @required this.builder  //数据快照   回调函数,暴露异步处理中的快照。这个是我们构建组件的主要组成。 主要来看一下它的构造函数:  }) : assert(builder != null),       super(key: key);
class _MyHomePageState extends State {  Future mockNetworkData() async {    return Future.delayed(Duration(seconds: 2), () => "我是从互联网上获取的数据");  }  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: Text(widget.title),      ),      body: Center(        child: Column(          mainAxisAlignment: MainAxisAlignment.center,          children: [            Text(              'You have pushed the button this many times:',            ),            FutureBuilder(              future: mockNetworkData(),                builder: (BuildContext context, AsyncSnapshot snapshot){              if(snapshot.connectionState == ConnectionState.done){                if(snapshot.hasError){                  // 请求失败,显示错误                  return Text("Error: ${snapshot.error}");                }else {                  // 请求成功,显示数据                  return Text("Contents: ${snapshot.data}");                }              }else {                return CircularProgressIndicator();              }            }),          ],        ),      ), // This trailing comma makes auto-formatting nicer for build methods.    );  }}

SteamBuilder的使用

class _MyHomePageState extends State {  Stream counter(){    return Stream.periodic(Duration(seconds: 1), (i){      return i;    });  }  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: Text(widget.title),      ),      body: Center(        child: Column(          mainAxisAlignment: MainAxisAlignment.center,          children: [            Text(              'You have pushed the button this many times:',            ),            StreamBuilder(                stream: counter(),                builder: (BuildContext context, AsyncSnapshot snapshot){                  if(snapshot.hasError){                    return Text("Error: ${snapshot.error}");                  }                  switch (snapshot.connectionState){                    case ConnectionState.none:                      return Text("没有Stream");                    case ConnectionState.waiting:                      return Text("等待数据、、、");                    case ConnectionState.active:                      return Text("active: ${snapshot.data}");                    case ConnectionState.done:                      return Text("Stream已关闭");                  }                  return null;                }),          ],        ),      ), // This trailing comma makes auto-formatting nicer for build methods.    );  }}

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

来源地址:https://blog.csdn.net/qq_27909209/article/details/130523131

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯