Flutter 局部刷新

这篇具有很好参考价值的文章主要介绍了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方法。

  //请求刷新
  setState((){
    
  });
 
 
  #State<T extends StatefulWidget>
  @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<StatefulWidget> createState() {
    return PartRefreshWidgetState(_child);
  }
 
}
 
class PartRefreshWidgetState extends State<PartRefreshWidget> {
 
  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<GlobalKeyDemo> {
  int _count = 0;
 
  //使用1 创建GlobalKey
  GlobalKey<PartRefreshWidgetState> 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: <Widget>[
              //使用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<MyHomePage> {

  Future<String> 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: <Widget>[
            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<MyHomePage> {

  Stream<int> 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: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            StreamBuilder(
                stream: counter(),
                builder: (BuildContext context, AsyncSnapshot<int> 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://www.toymoban.com/news/detail-454511.html

到了这里,关于Flutter 局部刷新的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flutter 使用bloc模拟首页实现下拉刷新

    思考:这篇文章主要是记录bloc与下拉刷新功能的使用 本篇文章是延续上一篇文章中所包含的bloc和自定义http库的使用,使用发现在上一篇文章中对bloc的理解有些误区导致最后实现好几个方式都感觉不尽人意,最终尝试查看官方示例与个人示例进行比对后发现了问题所在, 下面

    2024年02月11日
    浏览(27)
  • Flutter页面刷新失败?看看是不是这个原因

    我用flutter开发了一个页面,页面上有一些自己写的控件A,A控件里有一个button,我点击这个A控件里的button的时候,直接在onPressed里调用setState发现页面并没有刷新。 要实现控件A所在页面的整体刷新要怎么实现呢? 在Flutter中,要实现点击控件A中的按钮后刷新整个页面,你可

    2024年02月05日
    浏览(33)
  • 详解flutter刷新流程,让你的应用更流畅

    本文已授权公众号【缦图技术团队】发布 详解flutter刷新流程,让你的应用更流畅 一、概述 Flutter  是谷歌推出的高性能、跨端 UI 框架,可以通过一套代码,支持  iOS 、 Android 、 Windows/MAC/Linux  等多个平台,且能达到原生性能。 Flutter  也可以与平台原生代码进行混合开发,

    2024年02月15日
    浏览(34)
  • Flutter 库:强大的下拉刷新上拉加载框架——EasyRefresh

    EasyRefresh 是一个用于 Flutter 应用程序的简单易用的 下拉刷新 和 上拉加载 框架。它支持几乎所有的 Flutter 可滚动小部件。它的功能与Android 的 SmartRefreshLayout 非常相似,并吸收了许多第三方库的优点。EasyRefresh 集成了各种样式的页眉和页脚,但没有任何限制,您可以轻松自定

    2024年01月19日
    浏览(30)
  • flutter开发实战-下拉刷新与上拉加载更多实现

    flutter开发实战-下拉刷新与上拉加载更多实现 在开发中经常遇到列表需要下拉刷新与上拉加载更多,这里使用EasyRefresh,版本是3.3.2+1 EasyRefresh可以在Flutter应用程序上轻松实现下拉刷新和上拉加载。它几乎支持所有Flutter Scrollable小部件。它的功能与安卓的SmartRefreshLayout非常相似

    2024年02月07日
    浏览(33)
  • Flutter路由的几种用法

    Flutter路由跳转 search.dart页面 命名路由跳转需要先配置路由 routers.dart配置文件 然后需要在首页添加initialRoute和onGenerateRoute配置 context属性中写配置中的路径,arguments属性中是跳转需要带的参数,跳转到form.dart页面并接收参数。 命名路由替换跳转用pushReplacementNamed,跳转新页面

    2024年02月04日
    浏览(30)
  • Flutter关于StatefulWidget中State刷新时机的一点实用理解

    刚入门flutter开发,使用StatefulWidget踩了很多坑,就我遇到典型问题谈谈见解。 1.initState方法只会在控件初始化的时候执行一遍。 2.控件内部执行setState方法,则会每次执行build方法。 3.控件销毁会执行dispose方法,所以一些未释放的资源可以在该方法中执行,例如计时器。 4.使

    2024年02月10日
    浏览(33)
  • flutter 常用布局方式

    单子 Widget是指只有一个子组件的Widget,这样布局Widget有三个:Container、Padding、Center Container,是一种允许在其内部添加其他控件的控件,也是 UI 框架中的一个常见概念。 在 Flutter 中,Container 本身可以单独作为控件存在(比如单独设置背景色、宽高),也可以作为其他控件的

    2024年02月08日
    浏览(30)
  • Flutter 平移动画 — 4种实现方式

    Flutter 旋转动画 — RotationTransition Flutter 平移动画 — 4种实现方式 Flutter 淡入淡出与逐渐出现动画 Flutter 尺寸缩放、形状、颜色、阴影变换动画 Flutter 列表Item动画 — AnimatedList实现Item左进左出、淡入淡出 Flutter Hero 实现共享元素转场动画 Flutter Hero 实现径向变换动画 — 圆形变

    2023年04月17日
    浏览(32)
  • Flutter 中数据存储的四种方式

    在 Flutter 中,存储是指用于本地和远程存储和管理数据的机制。以下是 Flutter 中不同存储选项的概述和示例。 Shared Preferences(本地键值存储) Shared Preferences 是一种在本地存储少量数据(例如用户首选项或设置)的简单方法。 它适合以持久的方式存储键值对。 shared_preferenc

    2024年02月03日
    浏览(22)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包