flutter怎么手动刷新_Flutter 组件刷新【实战】

本文介绍了在Flutter中如何使用Provider进行数据管理,通过监听Model数据变化实现Widget的自动刷新。详细展示了Model的创建、监听数据变化的方式以及如何封装Widget以简化代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

介绍一下数据与Widget之间传递,数据改变-->触发Widget刷新

1.0 所需工具

Provider

2.0 Provider

Provider 会在Widget和Model之间建立监听,以确保数据发生变化时刷新Widget

3.0 必要步骤:

Model 要继承ChangeNotifier

Widget要监听Model数据变化

Provider 是flutter推荐使用的状态管理工具,具体原理这里不展开分析,下面介绍一下如何快速使用,达到一个真实业务的场景.

4.0 Model创建

// 重要: model必须继承ChangeNotifier

class TestClass with ChangeNotifier {

var count = 1;

action() {

++count;

//数据变化后腰通过 notifyListeners() 通知所有监听者

notifyListeners();

}

}

4.1 监听Model

Model监听有两种方式

通过addListener方式

通过Provider.of(context)

4.1.1 通过 addListener 监听数据改变

当数据改变并且调用 notifyListeners() 这里会收到回调

model.addListener(() {

//Do something

});

4.1.2 通过 Provider.of(context) 方式监听

这里看到在build方法中我们获取Provider传入的Model.并没有调用addListener.这里解释一下.

通过查看 Provider.of 源码中知道, Provider.of通过 context 将本次构建的build方法绑定,并监听数据改变. 所以在数据变化后将自动调用 build 方法进行刷新.

@override

Widget build(BuildContext context) {

final model = Provider.of(context);

return Container()

}

5.1 向下传递完整示例

下面将一个Model向下传递的完整实例贴出来.

import 'package:provider/provider.dart';

void main() {

runApp(MyApp());

}

class TestClass with ChangeNotifier {

var count = 1;

action() {

++count;

notifyListeners();

}

}

class MyApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return ChangeNotifierProvider(

create: (context)=>TestClass(),

child: MaterialApp(

theme: ThemeData.dark(),

home: FirstScreen(),

),

);

}

}

class FirstScreen extends StatelessWidget {

@override

Widget build(BuildContext context) {

final model = Provider.of(context);

return Scaffold(

appBar: AppBar(

title: Text('Provider'),

),

body: Container(

child: Center(child: Text("${model.count}",style: TextStyle(fontSize: 50),),),

),

floatingActionButton: FloatingActionButton(

onPressed: () => model.action(),

child: Icon(Icons.add),

),

);

}

}

5.2 组件内部通过Model控制数据刷新 完整示例

import 'package:provider/provider.dart';

void main() {

runApp(MyApp());

}

class TestClass with ChangeNotifier {

var count = 1;

action() {

++count;

notifyListeners();

}

}

class MyApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return MaterialApp(

theme: ThemeData.dark(),

home: FirstScreen(),

);

}

}

class FirstScreen extends StatelessWidget {

final TestClass source=TestClass();

@override

Widget build(BuildContext context) {

return Scaffold(

appBar: AppBar(

title: Text('Provider'),

),

body:ChangeNotifierProvider(

create: (context) => source,

child: Consumer(

child: Container(),

builder: (context, model, child) {

return Container(

child: Center(child: Text("${model.count}",style: TextStyle(fontSize: 50),),),

);

},

),

),

floatingActionButton: FloatingActionButton(

onPressed: () => source.action(),

child: Icon(Icons.add),

),

);

}

}

6.0 Provider封装

由5.2 数据内部控制刷新示例看出,实际代码写起来比较麻烦.所以封装了一下. 只需要传入必要参数就可以.

6.1 封装Widget

class RefreshWidget extends StatelessWidget {

RefreshWidget(

this.builder, {

@required this.source,

this.child,

});

final T source;

final Function(BuildContext context, T value, Widget child) builder;

final Widget child;

static Builder(

Function(BuildContext context, T value, Widget child) builder) {

return builder;

}

@override

Widget build(BuildContext context) {

return ChangeNotifierProvider.value(

value: source,

child: Consumer(

child: child,

builder: (context, model, child) {

return builder(context, model, child);

},

),

);

}

}

6.2 封装后使用对比

封装前

ChangeNotifierProvider(

create: (context) => source,

child: Consumer(

child: Container(),

builder: (context, model, child) {

return Container(

child: Center(child: Text("${model.count}",style: TextStyle(fontSize: 50),),),

);

},

),

),

封装后

RefreshWidget(

(context, value, child) => Container(

child: Center(

child: Text(

"${value.count}",

style: TextStyle(fontSize: 50),

),

),

),

source: source),

封装后我们只需要关心下面三点,对与新手比较友好,不用纠结太多

builder构建方法(自动补全)

source数据model

model 类型

直接使用builder方法没有方法提示, 这点很不友好.

封装后将builder放到首位, 会将builder方法直接补全, 这才是我最终的目的, 可以有效减少control+c/v的次数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值